How to set non-selectable default text on QComboBox?

后端 未结 3 1380
没有蜡笔的小新
没有蜡笔的小新 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: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)

提交回复
热议问题