代码之家  ›  专栏  ›  技术社区  ›  JokerMartini

将委托分配给TreeView单元格

  •  0
  • JokerMartini  · 技术社区  · 6 年前

    目前我正在创建一个QTreeView,其中第三列委托被设置为一个组合框进行编辑。不过,我想让用户能够切换不同的视图与给定的数据,如下图所示。如下图所示,建议如何处理将组合框分配给指定单元格的正确行/列?

    平面列表版本工作得很好,我不知道如何处理其他显示选项。

    有没有一种方法可以设置为每行/列提供QComboBox作为编辑器的委托?

    enter image description here

    enter image description here

    import os, sys, pprint
    sys.path.append(os.environ.get('PS_SITEPACKAGES'))
    from Qt import QtGui, QtWidgets, QtCore   
    import pprint
    
    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.FLATLIST = {   
                'Leslie': [
                        {'fullname': 'medic_skin_v001', 'entity': 'Medic', 'type': 'Bulky'}
                    ],
                'Mike': [ 
                        {'fullname': 'tech_skin_v001', 'entity': 'Tech', 'type': 'Average'},
                        {'fullname': 'tech_skin_v002', 'entity': 'Tech', 'type': 'Average'}
                    ],
                'Kevin': [ 
                        {'fullname': 'tech_skin_v001', 'entity': 'Tech', 'type': 'Average'},
                    ],
                'Michelle': [
                        {'fullname': 'warrior_skin_v001', 'entity': 'Warrior', 'type': 'Athletic'},
                        {'fullname': 'warrior_skin_v002', 'entity': 'Warrior', 'type': 'Athletic'},
                        {'fullname': 'warrior_skin_v003', 'entity': 'Warrior', 'type': 'Athletic'}]
                }
    
    
            self.uiDisplayA = QtWidgets.QPushButton('Display Flat List')
            self.uiDisplayA.clicked.connect(self.slotDisplayA)
    
            self.uiDisplayB = QtWidgets.QPushButton('Display Grouped By Entity')
            self.uiDisplayB.clicked.connect(self.slotDisplayB)
    
            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.displayLayout = QtWidgets.QHBoxLayout()
            self.displayLayout.addWidget(self.uiDisplayA)
            self.displayLayout.addWidget(self.uiDisplayB)
    
            self.layout = QtWidgets.QVBoxLayout()
            self.layout.addLayout(self.displayLayout)
            self.layout.addWidget(self.uiSearch)
            self.layout.addWidget(self.uiVersionTreeView)
            self.setLayout(self.layout)
            # signals/slots
            self.uiSearch.textChanged.connect(self.versionProxyModel.setFilterWildcard)
            self.slotDisplayA()
    
    
        def group_by_entity(self, items):
            grouped = {}
            for k, v in items.items():
                if not v: continue
                key = v[0].get('entity', 'unknown')
                if key not in grouped.keys():
                    grouped[key] = {}
                grouped[key][k] = v
            return grouped
    
    
        def slotDisplayA(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'])
    
    
            for key, values in self.FLATLIST.items():
                col1 = QtGui.QStandardItem(values[0]['entity'])
                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)
    
    
        def slotDisplayB(self):
            sortColumn = self.uiVersionTreeView.header().sortIndicatorSection()
            sortDirection = self.uiVersionTreeView.header().sortIndicatorOrder()
            self.versionModel.clear()
            self.uiVersionTreeView.setSortingEnabled(False)
            self.versionModel.setHorizontalHeaderLabels(['Type', 'Name', 'Versions'])
    
            # add each entity
            ENTIYLIST = self.group_by_entity(self.FLATLIST)
    
            pprint.pprint(ENTIYLIST, indent=4)
            for key, values in ENTIYLIST.items():
                parent = QtGui.QStandardItem(key)
                self.versionModel.appendRow(parent)
    
                # add entity children
                for childKey, childValues in values.items():
                    child1 = QtGui.QStandardItem(childValues[0]['type'])
                    child2 = QtGui.QStandardItem(childKey)
                    child3 = QtGui.QStandardItem()
                    parent.appendRow([child1, child2, child3])
                    child1.setData(QtGui.QColor(80,150,200), role=QtCore.Qt.ForegroundRole)
    
            # 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_()
    
    0 回复  |  直到 6 年前