杨魅力
如果您检查代码的逻辑,您会发现组合框与 QModelIndex 高度相关,即如果 QModelIndex 消失,则 QComboBox 也将消失。在 QSortFilterProxyModel 的情况下,在进行过滤时正在消除和创建 QModelIndex,因此也消除了 QComboBox,并且它们不会被恢复,可能的解决方案是跟踪删除,但这非常复杂。另一个最佳解决方案是使用提供 QComboBox 作为编辑器的委托,这些 QComboBox 是按需创建的。import os, sys, pprintsys.path.append(os.environ.get('PS_SITEPACKAGES'))from Qt import QtGui, QtWidgets, QtCore class VersionProxyModel(QtCore.QSortFilterProxyModel): def __init__(self, *args, **kwargs): super(VersionProxyModel, self).__init__(*args, **kwargs) self.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) self.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) def checkParents(self, index): while (index.isValid()): if super(VersionProxyModel, self).filterAcceptsRow(index.row(), index.parent()): return True index = index.parent() return False def checkChildren(self, index): for i in range(0, self.sourceModel().rowCount(index)): if super(VersionProxyModel, self).filterAcceptsRow(i, index): return True # recursive for i in range(0, self.sourceModel().rowCount(index)): self.checkChildren(self.sourceModel().index(i, 0, index)) return False def filterAcceptsRow(self, source_row, parent): if super(VersionProxyModel, self).filterAcceptsRow(source_row, parent): return True if self.checkChildren(self.sourceModel().index(source_row, 0, parent)): return True return self.checkParents(parent)class ComboBoxDelegate(QtWidgets.QStyledItemDelegate): def paint(self, painter, option, index): if isinstance(self.parent(), QtWidgets.QAbstractItemView): self.parent().openPersistentEditor(index) super(ComboBoxDelegate, self).paint(painter, option, index) def createEditor(self, parent, option, index): editor = QtWidgets.QComboBox(parent) editor.currentIndexChanged.connect(self.commitEditor) return editor @QtCore.Slot() def commitEditor(self): editor = self.sender() self.commitData.emit(editor) if isinstance(self.parent(), QtWidgets.QAbstractItemView): self.parent().updateEditorGeometries() def setEditorData(self, editor, index): values = index.data(QtCore.Qt.UserRole + 100) val = index.data(QtCore.Qt.UserRole + 101) editor.clear() for i, x in enumerate(values): editor.addItem(x['fullname'], x) if val['fullname'] == x['fullname']: editor.setCurrentIndex(i) def setModelData(self, editor, model, index): values = index.data(QtCore.Qt.UserRole + 100) ix = editor.currentIndex() model.setData(index, values[ix] , QtCore.Qt.UserRole + 101) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect)class Window(QtWidgets.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.resize(800, 400) self.uiSearch = QtWidgets.QLineEdit() self.versionModel = QtGui.QStandardItemModel() self.versionProxyModel = VersionProxyModel() self.versionProxyModel.setSourceModel(self.versionModel) self.versionProxyModel.setDynamicSortFilter(True) self.uiVersionTreeView = QtWidgets.QTreeView() self.uiVersionTreeView.sortByColumn(0, QtCore.Qt.AscendingOrder) self.uiVersionTreeView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.uiVersionTreeView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.uiVersionTreeView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.uiVersionTreeView.setModel(self.versionProxyModel) self.uiVersionTreeView.setRootIsDecorated(False) delegate = ComboBoxDelegate(self.uiVersionTreeView) self.uiVersionTreeView.setItemDelegateForColumn(3, delegate) # layout self.layout = QtWidgets.QVBoxLayout() self.layout.addWidget(self.uiSearch) self.layout.addWidget(self.uiVersionTreeView) self.setLayout(self.layout) # signals/slots self.uiSearch.textChanged.connect(self.versionProxyModel.setFilterWildcard) self.populate() def populate(self): sortColumn = self.uiVersionTreeView.header().sortIndicatorSection() sortDirection = self.uiVersionTreeView.header().sortIndicatorOrder() self.versionModel.clear() self.uiVersionTreeView.setSortingEnabled(False) self.versionModel.setHorizontalHeaderLabels(['Entity', 'Type', 'Name', 'Versions']) versions = { 'Leslie': [ {'fullname': 'medic_skin_v001', 'name': 'Medic', 'type': 'Bulky'} ], 'Mike': [ {'fullname': 'tech_skin_v001', 'name': 'Tech', 'type': 'Average'}, {'fullname': 'tech_skin_v002', 'name': 'Master', 'type': 'Average'} ], 'Michelle': [ {'fullname': 'warrior_skin_v001', 'name': 'Warrior', 'type': 'Athletic'}, {'fullname': 'warrior_skin_v002', 'name': 'Warrior', 'type': 'Athletic'}, {'fullname': 'warrior_skin_v003', 'name': 'Warrior', 'type': 'Athletic'}] } for key, values in versions.items(): col1 = QtGui.QStandardItem(values[0]['name']) col2 = QtGui.QStandardItem(values[0]['type']) col3 = QtGui.QStandardItem(key) col4 = QtGui.QStandardItem() self.versionModel.appendRow([col1, col2, col3, col4]) col2.setData(QtGui.QColor(80,150,200), role=QtCore.Qt.ForegroundRole) col4.setData(values, QtCore.Qt.UserRole + 100) col4.setData(values[0], QtCore.Qt.UserRole + 101) # Restore self.uiVersionTreeView.setSortingEnabled(True) self.uiVersionTreeView.sortByColumn(sortColumn, sortDirection) self.uiVersionTreeView.expandAll() for i in range(self.versionModel.columnCount()): self.uiVersionTreeView.resizeColumnToContents(i)if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) ex = Window() ex.show() app.exec_()分享