我希望能够过滤“参数”列下的每个项目。我正在使用QSortFilterProxyModel和QLineEdit尝试从QTreeView筛选出特定级别,但是我无法筛选出除“根级别”之外的任何级别/子级别。
如何解决此实现,使其能够过滤任何级别,而不仅仅是“ 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_())
答案 0 :(得分:2)
如果要过滤第二列,则必须使用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_())