小部件从QTreeview中消失

时间:2018-12-10 01:52:05

标签: python pyside qtreeview

在清除搜索过滤器字段后,为什么组合框从树视图中消失了?

启动应用程序如下所示: enter image description here

然后,我使用可以按预期工作的QLineEdit进行搜索: 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


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 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)

        # 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.searchFilterChanged)
        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])

            # set data 
            col2.setData(QtGui.QColor(80,150,200), role=QtCore.Qt.ForegroundRole)

            combo = QtWidgets.QComboBox()
            for x in values:
                combo.addItem(x['fullname'], x)

            mIndex = self.versionProxyModel.mapFromSource(col4.index())
            self.uiVersionTreeView.setIndexWidget(mIndex, combo)

        # Restore
        self.uiVersionTreeView.setSortingEnabled(True)
        self.uiVersionTreeView.setSortingEnabled(True)
        self.uiVersionTreeView.sortByColumn(sortColumn, sortDirection)
        self.uiVersionTreeView.expandAll()
        for i in range(self.versionModel.columnCount()):
            self.uiVersionTreeView.resizeColumnToContents(i)


    def searchFilterChanged(self, text):
        self.versionProxyModel.setFilterWildcard(text)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = Window()
    ex.show()
    app.exec_()

1 个答案:

答案 0 :(得分:1)

如果检查代码的逻辑,您将看到组合框与QModelIndex高度相关,也就是说,如果QModelIndex消失,QComboBox也将消失。对于QSortFilterProxyModel,在进行过滤时将消除并创建QModelIndex,因此也消除了QComboBox,并且它们将不会被还原,一种可能的解决方案是跟踪删除操作,但这非常复杂。另一个最佳解决方案是使用提供QComboBox的委托作为编辑器,并根据需要创建这些QComboBox。

User-Agent