Reputation: 720
I want to be able to filter every item under the 'Parameter' column. I am using a QSortFilterProxyModel and a QLineEdit to try and filter out specific levels from the QTreeView, however I unable to filter out any level/sublevel besides the 'Rootlevel'.
How can I fix this implementation to be able to filter any of the levels and not just the '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_())
Upvotes: 1
Views: 1744
Reputation: 243907
If you want to filter the second column then you must set it using the filterKeyColumn
property, if you want to filter at lower levels then you must enable the recursiveFilteringEnabled
property, and it is recommended that you expand all the items using expandAll()
so that the filtering is visible.
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_())
Upvotes: 4