How to set non-selectable default text on QComboBox?

后端 未结 3 1371
没有蜡笔的小新
没有蜡笔的小新 2020-12-06 09:54

Using a regular QComboBox populated with items, if currentIndex is set to -1, the widget is empty. It would be very useful to instead

相关标签:
3条回答
  • 2020-12-06 10:13

    It doesn't appear that case was anticipated in the Combo Box API. But with the underlying model flexibility it seems you should be able to add your --Select Country-- as a first "legitimate" item, and then keep it from being user selectable:

    QStandardItemModel* model =
            qobject_cast<QStandardItemModel*>(comboBox->model());
    QModelIndex firstIndex = model->index(0, comboBox->modelColumn(),
            comboBox->rootModelIndex());
    QStandardItem* firstItem = model->itemFromIndex(firstIndex);
    firstItem->setSelectable(false);
    

    Depending on what precise behavior you want, you might want to use setEnabled instead. Or I'd personally prefer it if it was just a different color item that I could set it back to:

    Qt, How do I change the text color of one item of a QComboBox? (C++)

    (I don't like it when I click on something and then get trapped to where I can't get back where I was, even if it's a nothing-selected-yet-state!)

    0 讨论(0)
  • 2020-12-06 10:13

    One way you can do something similar is to set a placeholder:

    comboBox->setPlaceholderText(QStringLiteral("--Select Country--"));
    comboBox->setCurrentIndex(-1);
    

    This way you have a default that cannot be selected.

    0 讨论(0)
  • 2020-12-06 10:29

    Leaving my solution here from PyQt5. Create a proxy model and shift all the rows down one, and return a default value at row 0.

    class NullRowProxyModel(QAbstractProxyModel):
        """Creates an empty row at the top for null selections on combo boxes
        """
    
        def __init__(self, src, text='---', parent=None):
            super(NullRowProxyModel, self).__init__(parent)
            self._text = text
            self.setSourceModel(src)
    
        def mapToSource(self, proxyIndex: QModelIndex) -> QModelIndex:
            if self.sourceModel():
                return self.sourceModel().index(proxyIndex.row()-1, proxyIndex.column())
            else:
                return QModelIndex()
    
        def mapFromSource(self, sourceIndex: QModelIndex) -> QModelIndex:
            return self.index(sourceIndex.row()+1, sourceIndex.column())
    
        def data(self, proxyIndex: QModelIndex, role=Qt.DisplayRole) -> typing.Any:
            if proxyIndex.row() == 0 and role == Qt.DisplayRole:
                return self._text
            elif proxyIndex.row() == 0 and role == Qt.EditRole:
                return None
            else:
                return super(NullRowProxyModel, self).data(proxyIndex, role)
    
        def index(self, row: int, column: int, parent: QModelIndex = ...) -> QModelIndex:
            return self.createIndex(row, column)
    
        def parent(self, child: QModelIndex) -> QModelIndex:
            return QModelIndex()
    
        def rowCount(self, parent: QModelIndex = ...) -> int:
            return self.sourceModel().rowCount()+1 if self.sourceModel() else 0
    
        def columnCount(self, parent: QModelIndex = ...) -> int:
            return self.sourceModel().columnCount() if self.sourceModel() else 0
    
        def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any:
            if not self.sourceModel():
                return None
            if orientation == Qt.Vertical:
                return self.sourceModel().headerData(section-1, orientation, role)
            else:
                return self.sourceModel().headerData(section, orientation, role)
    0 讨论(0)
提交回复
热议问题