I have an application which displays JSON-file to the QTreeView. For this I created my own QJsonTreeModel(QAbstractItemModel)
class for QTreeView model
In my MainWindow.py
I implemented it like this:
class MainWindow(QMainWindow):
def __init__(self, json_text: dict) -> None:
self.tree_view = QTreeView()
self.model = QJsonTreeModel()
self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
self.tree_view.customContextMenuRequested.connect(self.open_right_click_menu)
self.tree_view.setModel(self.model)
self.model.load(self.json_text)
def open_right_click_menu(self, position) -> None:
index = self.tree_view.selectionModel().currentIndex()
parent = index.parent()
if not index.isValid():
return
# workes fine
print(self.model.data(self.tree_view.selectedIndexes()[2], Qt.EditRole))
It works perfect but recently I needed to add search QLineEdit() field to find the input element in the tree. And for this task I found soultion with QSortFilterProxyModel()
. Which I implemented like this:
class MainWindow(QMainWindow):
def __init__(self, json_text: dict) -> None:
self.tree_view = QTreeView()
self.line_edit = QLineEdit()
self.model = QJsonTreeModel()
self.model.load(self.json_text)
self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
self.tree_view.customContextMenuRequested.connect(self.open_right_click_menu)
self.filter_proxy_model = QSortFilterProxyModel()
self.filter_proxy_model.setSourceModel(self.model)
self.filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) # Qt.CaseSensitive
self.filter_proxy_model.setRecursiveFilteringEnabled(True)
self.filter_proxy_model.setFilterKeyColumn(-1)
self.tree_view.setModel(self.filter_proxy_model)
self.line_edit.textChanged.connect(self.filter_proxy_model.setFilterRegExp)
def open_right_click_menu(self, position) -> None:
index = self.tree_view.selectionModel().currentIndex()
parent = index.parent()
if not index.isValid():
return
# not working rn. Segmentation fault
print(self.model.data(self.tree_view.selectedIndexes()[2], Qt.EditRole))
# also not working
print(self.filter_proxy_model.sourceModel().data(self.tree_view.selectedIndexes()[2], Qt.EditRole))
It works fine, the input text is searched in the tree and displayed normally, but the problem is in other place. I have implemented right click menu for my QTreeView:
self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
self.tree_view.customContextMenuRequested.connect(self.open_right_click_menu)
And in open_right_click_menu
function I need to call self.model.data(self.tree_view.selectedIndexes()[2], Qt.EditRole)
(index is correct, there are three columns) function or some another function of QJsonTreeModel()
class which worked perfectly before adding QSortFilterProxyModel()
. But after implementing QSortFilterProxyModel()
I have got Segmentation fault when I am trying to call some function of QJsonTreeModel()
class. Also I tried self.filter_proxy_model.sourceModel().data(self.tree_view.selectedIndexes()[2], Qt.EditRole)
but it also causes Segmentation fault. Where am I wrong and how do I call functions of QJsonTreeModel()
class properly?
I didn't find this question before I asked mine, but the problem was that I did`t map QSortFilterProxyModel back. So the solution is this:
def open_right_click_menu(self, position) -> None:
# not working version
print(self.model.data(self.tree_view.selectedIndexes()[2], Qt.EditRole))
# working version
print(self.model.data(
self.filter_proxy_model.mapToSource(self.tree_view.selectedIndexes()[2]), Qt.EditRole))