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?
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
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.
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:
On Windows there may be a different issue: text of the checkBoxes has sticked background or dotted border around an item:
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:
I tried to make this example on Linux Mint, but I can't make the checkboxes visible.
I had to implement the SubclassOfQStyledItemDelegate
class and set the delegate to the checkbox as Neptilo and gshep advised.
You can try this with QListView
:
QStringList values = QStringList << "check 1" << "check 2" << "check 3" << "check 4";
QStandardItemModel model = new QStandardItemModel;
for (int i = 0; i < values.count(); i++)
{
QStandardItem *item = new QStandardItem();
item->setText(values[i]);
item->setCheckable(true);
item->setCheckState(Qt::Unchecked);
model->setItem(i, item);
}
ui->list->setModel(model);