【问题标题】:How to filter sub-items, QTreeView using QSortFilterProxyModel如何过滤子项,QTreeView 使用 QSortFilterProxyModel
【发布时间】:2019-07-23 05:35:52
【问题描述】:

我希望能够过滤“参数”列下的每个项目。我正在使用 QSortFilterProxyModel 和 QLineEdit 尝试从 QTreeView 中过滤掉特定级别,但是我无法过滤掉除“Rootlevel”之外的任何级别/子级别。

如何修复此实现以过滤任何级别而不仅仅是“RootLevel”?

from PyQt5 import QtGui,QtCore,QtWidgets
import sys

class MainFrame(QtWidgets.QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)

        tree = {'RootLevel':{
                    "Level1": {"Level1_item1":14, "Level1_item2":12, "Level1_item3":3.55},
                    "Level2": {
                        "Level2_SubLevel1": {"Level2_SubLevel1_item1":3.52, "Level2_SubLevel1_item2":2.55, "Level2_SubLevel1_item3":13},
                        "Level2_SubLevel2": {"Level2_SubLevel2_item1":2, "Level2_SubLevel2_item2":4, "Level2_SubLevel2_item3":3.11}
                        },
                    "Level3": {"Level3_item1":12, "Level3_item2":13.55, "Level3_item3":122}}
        }

        self.tree = QtWidgets.QTreeView(self)
        self.filterEdit = QtWidgets.QLineEdit()
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.filterEdit)
        layout.addWidget(self.tree)

        self.root_model = QtGui.QStandardItemModel()
        self.root_model.setHorizontalHeaderLabels(['Level','Values'])

        self.fill_model_from_json(self.root_model.invisibleRootItem(), tree)

        self.proxyModel = QtCore.QSortFilterProxyModel(self)
        self.proxyModel.setSourceModel(self.root_model)

        self.tree.setModel(self.proxyModel)
        self.tree.header().setMinimumSectionSize(300)
        self.filterEdit.textChanged.connect(self.onTextChanged)

    @QtCore.pyqtSlot(str)
    def onTextChanged(self, text):
        self.proxyModel.setFilterRegExp(text)

    def fill_model_from_json(self, parent, d):
        if isinstance(d, dict):
            for key, value in d.items():
                it = QtGui.QStandardItem(str(key))
                if isinstance(value, dict):
                    parent.appendRow(it)
                    self.fill_model_from_json(it, value)
                else:
                    it2 = QtGui.QStandardItem(str(value))
                    parent.appendRow([it, it2])

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = MainFrame()
    main.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qsortfilterproxymodel


    【解决方案1】:

    如果要过滤第二列,则必须使用filterKeyColumn属性进行设置,如果要在较低级别进行过滤,则必须启用recursiveFilteringEnabled属性,建议您展开所有使用expandAll() 的项目,以便过滤可见。

    from PyQt5 import QtGui, QtCore, QtWidgets
    
    
    class MainFrame(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            tree = {
                "RootLevel": {
                    "Level1": {
                        "Level1_item1": 14,
                        "Level1_item2": 12,
                        "Level1_item3": 3.55,
                    },
                    "Level2": {
                        "Level2_SubLevel1": {
                            "Level2_SubLevel1_item1": 3.52,
                            "Level2_SubLevel1_item2": 2.55,
                            "Level2_SubLevel1_item3": 13,
                        },
                        "Level2_SubLevel2": {
                            "Level2_SubLevel2_item1": 2,
                            "Level2_SubLevel2_item2": 4,
                            "Level2_SubLevel2_item3": 3.11,
                        },
                    },
                    "Level3": {
                        "Level3_item1": 12,
                        "Level3_item2": 13.55,
                        "Level3_item3": 122,
                    },
                }
            }
    
            self.tree = QtWidgets.QTreeView()
            self.filterEdit = QtWidgets.QLineEdit(textChanged=self.onTextChanged)
            layout = QtWidgets.QVBoxLayout(self)
            layout.addWidget(self.filterEdit)
            layout.addWidget(self.tree)
    
            self.root_model = QtGui.QStandardItemModel()
            self.root_model.setHorizontalHeaderLabels(["Level", "Values"])
    
            self.fill_model_from_json(self.root_model.invisibleRootItem(), tree)
    
            self.proxyModel = QtCore.QSortFilterProxyModel(
                self, filterKeyColumn=1, recursiveFilteringEnabled=True
            )
            self.proxyModel.setSourceModel(self.root_model)
    
            self.tree.setModel(self.proxyModel)
            self.tree.header().setMinimumSectionSize(300)
    
            self.tree.expandAll()
            self.resize(640, 480)
    
        @QtCore.pyqtSlot(str)
        def onTextChanged(self, text):
            self.proxyModel.setFilterRegExp(text)
    
        def fill_model_from_json(self, parent, d):
            if isinstance(d, dict):
                for key, value in d.items():
                    it = QtGui.QStandardItem(str(key))
                    if isinstance(value, dict):
                        parent.appendRow(it)
                        self.fill_model_from_json(it, value)
                    else:
                        it2 = QtGui.QStandardItem(str(value))
                        parent.appendRow([it, it2])
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        main = MainFrame()
        main.show()
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 2015-06-16
      • 2015-11-17
      • 1970-01-01
      • 2018-04-02
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多