Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable specific items in QComboBox

Tags:

qt

In my application, I want to disable some items (i.e. not selectable, no highlights when mouse hovering above, and the texts are greyed out) in the QComboBox when certain conditions are met.

I indeed found someone did ask the same question here: Disable Item in Qt Combobox But none of these solutions in the answers seem to actually work (including the trick).

Is there a decent and 'correct' way to implement this?

EDIT:

I found out why setting the flags wouldn't disable the items in my application: for some reasons, I had to set the style QStyle::SH_ComboBox_UseNativePopup(see https://codereview.qt-project.org/#/c/82718/). And this setting for some reasons blocked the flag setting. Does anyone have an idea why, and how to work around? A minimum test example is included (modified from the answer of @Mike):

#include <QApplication>
#include <QComboBox>
#include <QStandardItemModel>
#include <QProxyStyle>

class ComboBoxStyle : public QProxyStyle
{
public:
    int styleHint ( StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0 ) const override
    {
        if ( hint == QStyle::SH_ComboBox_UseNativePopup )
        {
            return 1;
        }
        return QProxyStyle::styleHint( hint, option, widget, returnData );
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QComboBox comboBox;

    // Setting this style would block the flag settings later on.
    comboBox.setStyle( new ComboBoxStyle() );

    comboBox.insertItem(0, QObject::tr("item1"));
    comboBox.insertItem(1, QObject::tr("item2"));

    QStandardItemModel* model = qobject_cast<QStandardItemModel*>(comboBox.model());
    QStandardItem* item= model->item(1);
    item->setFlags(item->flags() & ~Qt::ItemIsEnabled);

    comboBox.show();
    return a.exec();
}
like image 660
Wayee Avatar asked Aug 12 '16 09:08

Wayee


2 Answers

Here is the technique @Mike describes, wrapped up in a convenient utility function:

void SetComboBoxItemEnabled(QComboBox * comboBox, int index, bool enabled)
{
    auto * model = qobject_cast<QStandardItemModel*>(comboBox->model());
    assert(model);
    if(!model) return;

    auto * item = model->item(index);
    assert(item);
    if(!item) return;
    item->setEnabled(enabled);
}
like image 80
Parker Coates Avatar answered Oct 24 '22 01:10

Parker Coates


The answer linked in my comment above seems to be talking about an old version of Qt. I have tested on Qt5.4 and Qt5.6 and there is no need set the color yourself here, you just need to set and/or clear the Qt::ItemIsEnabled flag, here is an example:

#include <QtWidgets>

int main(int argc, char *argv[]) {
  QApplication a(argc, argv);
  QComboBox comboBox;
  comboBox.addItem(QObject::tr("item1"));
  comboBox.addItem(QObject::tr("item2"));
  comboBox.addItem(QObject::tr("item3"));
  QStandardItemModel *model =
      qobject_cast<QStandardItemModel *>(comboBox.model());
  Q_ASSERT(model != nullptr);
  bool disabled = true;
  QStandardItem *item = model->item(2);
  item->setFlags(disabled ? item->flags() & ~Qt::ItemIsEnabled
                          : item->flags() | Qt::ItemIsEnabled);
  comboBox.show();
  return a.exec();
}
like image 23
Mike Avatar answered Oct 23 '22 23:10

Mike