2016-08-12 103 views
2

在我的应用程序中,当某些条件满足时,我想在QComboBox中禁用某些项目(即不能选择,鼠标悬停在上方时不亮,文本变灰)。禁用QComboBox中的特定项目

我确实发现有人在这里问过同样的问题:Disable Item in Qt Combobox 但是答案中的这些解决方案似乎都没有实际工作(包括技巧)。

是否有体面和“正确”的方式来实现这一点?

编辑:

我找到了原因设置标志在我的应用程序不会禁用的物品:由于某些原因,我不得不设置样式QStyle::SH_ComboBox_UseNativePopup(见https://codereview.qt-project.org/#/c/82718/)。由于某些原因,此设置会阻止标志设置。有没有人有一个想法,为什么,以及如何解决?最小的测试示例包括(从@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(); 
} 
+0

你尝试[这](http://stackoverflow.com/a/21740341/2666212)回答?如果你没有在你的'QComboBox'中使用'setModel'(即你使用'addItem'添加你的项目),这应该适合你。 – Mike

回答

7

在我的评论链接的答案似乎是在谈论一个老版本的Qt。我已经在Qt5.4和Qt5.6测试,也没有必要设置颜色自己这里,你只需要设置和/或清除Qt::ItemIsEnabled标志,这里有一个例子:

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

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()); 
    bool disabled= true; 
    QStandardItem* item= model->item(2); 
    item->setFlags(disabled? item->flags() & ~Qt::ItemIsEnabled: 
          item->flags() | Qt::ItemIsEnabled); 
    comboBox.show(); 
    return a.exec(); 
} 
+0

请注意,这依赖于未记录的行为,即将后备模型转换为'QStandardItemModel'。这与包括私人标题相同的警告。 –

+0

作为替代方法,显式创建一个'QStandardItemModel'实例并首先将它设置在组合框上。 –

+0

@JonHarper,不,这不是无证的,请阅读[this](https://doc.qt.io/qt-5/qcombobox.html#details)。 * QComboBox为其弹出列表使用模型/视图框架并存储其项目。默认情况下,** QStandardItemModel **存储项目,而QListView子类将显示弹出列表*。 – Mike