I can\'t find a standard way to disable an individual item in a Qt combo box. Is there a facility to do this in Qt that I am missing?
Why hack.. We know the model is a QStandardItemModel...
model = dynamic_cast< QStandardItemModel * >( combobox->model() );
item = model->item( row, col );
item->setEnabled( false );
Clean, elegant, and no hack...
You can use the model of a QListWidget
as a proxy.
QComboBox *combo = new QComboBox(this);
QListWidget *contents = new QListWidget(combo);
contents->hide();
combo->setModel(contents->model());
/* Populate contents */
contents->addItem("..."); // Etcetera
Then, this method will disable an item:
void disableItem(int index)
{
QListWidgetItem *item = contents->item(index);
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
}
In case your combo box is using a QStandardItemModel
(which it does by default) then you may stay away from the Qt::UserRole -1
hack (see blog post to which Desmond refers to in his answer above):
const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(ui->comboBox->model());
QStandardItem* item = model->item(1);
item->setFlags(disable ? item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)
: Qt::ItemIsSelectable|Qt::ItemIsEnabled));
// visually disable by greying out - works only if combobox has been painted already and palette returns the wanted color
item->setData(disable ? ui->comboBox->palette().color(QPalette::Disabled, QPalette::Text)
: QVariant(), // clear item data in order to use default color
Qt::TextColorRole);
Above code is a revised and more generic solution to my comment to the blog post.
Taken from here:
// Get the index of the value to disable
QModelIndex index = ui.comboBox->model()->index(1, 0);
// This is the effective 'disable' flag
QVariant v(0);
// the magic
ui.comboBox->model()->setData(index, v, Qt::UserRole - 1);
To enable again use:
QVariant v(1 | 32);
The model used maps the flags
word to Qt::UserRole - 1
-- that's what makes this code work. It's not a generic solution that would work with an arbitrary model.