Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ComboBox of CheckBoxes?

Tags:

qt

qt4

I am trying to make the items in a ComboBox checkable. I tried this:

http://programmingexamples.net/wiki/Qt/ModelView/ComboBoxOfCheckBoxes

where I subclassed QStandardItemModel and re-implemented the flags() function to make the items checkable. Then I added this model to the ComboBox. Unfortunately, a checkbox does not appear with the items. Can anyone see where I have gone wrong?

like image 638
David Doria Avatar asked Dec 07 '11 21:12

David Doria


People also ask

What is ComboBox check box?

Check boxes are labeled options that allow the user to select multiple options at once. Thus, any, all, or none of a set of check boxes may be selected. Combo boxes are drop-down menus that can appear along with other widgets in the main area of a window.

What is the function of combo box?

A ComboBox displays a text box combined with a ListBox, which enables the user to select items from the list or enter a new value. The DropDownStyle property specifies whether the list is always displayed or whether the list is displayed in a drop-down.

What is the difference between check box combo box and radio button?

Checkboxes and radio buttons are elements for making selections. Checkboxes allow the user to choose items from a fixed number of alternatives, while radio buttons allow the user to choose exactly one item from a list of several predefined alternatives.


2 Answers

Have you set a check state as well as making them checkable?

In my example below, this line is critical:

item->setData(Qt::Unchecked, Qt::CheckStateRole);

If it is omitted the check boxes won't render as there isn't a valid check-state to render.

The example shows check boxes in a combobox, list and table, as I couldn't get it to work at first either, so I tried different views.

test.cpp

#include <QtGui>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    QStandardItemModel model(3, 1); // 3 rows, 1 col
    for (int r = 0; r < 3; ++r)
    {
        QStandardItem* item = new QStandardItem(QString("Item %0").arg(r));

        item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
        item->setData(Qt::Unchecked, Qt::CheckStateRole);

        model.setItem(r, 0, item);
    }

    QComboBox* combo = new QComboBox();
    combo->setModel(&model);

    QListView* list = new QListView();
    list->setModel(&model);

    QTableView* table = new QTableView();
    table->setModel(&model);

    QWidget container;
    QVBoxLayout* containerLayout = new QVBoxLayout();
    container.setLayout(containerLayout);
    containerLayout->addWidget(combo);
    containerLayout->addWidget(list);
    containerLayout->addWidget(table);

    container.show();

    return app.exec();
}

test.pro

QT=core gui
SOURCES=test.cpp
like image 132
Silas Parker Avatar answered Oct 13 '22 01:10

Silas Parker


I have a little addition.

If one compiles the skyhisi's code then the combobox on Mac OS X doesn't look as combobox with native checkboxes. You can see it on the screenshot.

enter image description here

Tested with qt-4.8.5 and 5.1.1.

It seems like Qt draws these controls by itself. Our team has found the following workaround by pure accident. You can subclass QStyledItemDelegate and reimplement paint() this way:

void SubclassOfQStyledItemDelegate::paint(QPainter * painter_, const QStyleOptionViewItem & option_, const QModelIndex & index_) const
{
    QStyleOptionViewItem & refToNonConstOption = const_cast<QStyleOptionViewItem &>(option_);
    refToNonConstOption.showDecorationSelected = false;
    //refToNonConstOption.state &= ~QStyle::State_HasFocus & ~QStyle::State_MouseOver;

    QStyledItemDelegate::paint(painter_, refToNonConstOption, index_);
}

You can then set this delegate to the combo box by adding the following lines to skyhisi's code:

SubclassOfQStyledItemDelegate *delegate = new SubclassOfQStyledItemDelegate(this);
combo->setItemDelegate(delegate);

The comboBox installed with this delegate looks the following way: enter image description here

On Windows there may be a different issue: text of the checkBoxes has sticked background or dotted border around an item:

enter image description here

To change this appearance one can add the following line to the overridden paint just before the line QStyledItemDelegate::paint(painter_, refToNonConstOption, index_) (in the code sample this line was commented):

refToNonConstOption.state &= ~QStyle::State_HasFocus & ~QStyle::State_MouseOver;

Result:

enter image description here

like image 26
gshep Avatar answered Oct 13 '22 00:10

gshep