Selection change on key press in QTreeView
-
I have a relatively simple task - I need to get the currently selected item details from QTreeView after the user pressed a key.
Simple scenario: the user clicks some element in the tree and then presses "arrow down" key. I need to get the element that is currently in focus. I haven't found the built-in mechanism in QTreeView for getting the key pressed events, so I'm usingeventFilter()
.I expect that after user presses a key
currentIndex()
changes and I can get the value, however this doesn't happen. If you run the example below you'll see that the function returns the currently selected file on mouse click, but if you press arrow up/down after that the selection seems to "lag" - it shows the file from the previously selected index. However, if you press the arrow up/down and then something else, for example, Enter, it will return the expected result.What am I missing?
Thanks.from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * if __name__ == '__main__': class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.initUI() self.model = QFileSystemModel() self.model.setRootPath(".") self.view.setModel(self.model) self.view.setRootIndex(self.model.index(".")) self.view.clicked.connect(self.print_item) self.view.installEventFilter(self) def eventFilter(self, source, event): if source == self.view: if event.type() == QEvent.KeyPress: self.print_item() return False return super(Dialog, self).eventFilter(source, event) def print_item(self): print(self.model.filePath(self.view.currentIndex())) def initUI(self): self.view = QTreeView(self) self.view.setWindowTitle('Simple Tree Model') self.view.setGeometry(10, 10, 400, 300) self.setGeometry(300, 300, 420, 320) import sys app = QApplication(sys.argv) dialog = Dialog() dialog.show() sys.exit(app.exec_())
-
I have a relatively simple task - I need to get the currently selected item details from QTreeView after the user pressed a key.
Simple scenario: the user clicks some element in the tree and then presses "arrow down" key. I need to get the element that is currently in focus. I haven't found the built-in mechanism in QTreeView for getting the key pressed events, so I'm usingeventFilter()
.I expect that after user presses a key
currentIndex()
changes and I can get the value, however this doesn't happen. If you run the example below you'll see that the function returns the currently selected file on mouse click, but if you press arrow up/down after that the selection seems to "lag" - it shows the file from the previously selected index. However, if you press the arrow up/down and then something else, for example, Enter, it will return the expected result.What am I missing?
Thanks.from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * if __name__ == '__main__': class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.initUI() self.model = QFileSystemModel() self.model.setRootPath(".") self.view.setModel(self.model) self.view.setRootIndex(self.model.index(".")) self.view.clicked.connect(self.print_item) self.view.installEventFilter(self) def eventFilter(self, source, event): if source == self.view: if event.type() == QEvent.KeyPress: self.print_item() return False return super(Dialog, self).eventFilter(source, event) def print_item(self): print(self.model.filePath(self.view.currentIndex())) def initUI(self): self.view = QTreeView(self) self.view.setWindowTitle('Simple Tree Model') self.view.setGeometry(10, 10, 400, 300) self.setGeometry(300, 300, 420, 320) import sys app = QApplication(sys.argv) dialog = Dialog() dialog.show() sys.exit(app.exec_())
@midnightdim
Purely at a guess: the selection won't have changed till after you have allowed the default Qt handling of the key press? Whereas in youreventFilter()
you do it before the default. Try something like:def eventFilter(self, source, event): result = super(Dialog, self).eventFilter(source, event) if source == self.view: if event.type() == QEvent.KeyPress: self.print_item() return False return result
Separate question from why you need even filter at all, not just handle
currentChanged
/selectionChanged
? -
@midnightdim
Purely at a guess: the selection won't have changed till after you have allowed the default Qt handling of the key press? Whereas in youreventFilter()
you do it before the default. Try something like:def eventFilter(self, source, event): result = super(Dialog, self).eventFilter(source, event) if source == self.view: if event.type() == QEvent.KeyPress: self.print_item() return False return result
Separate question from why you need even filter at all, not just handle
currentChanged
/selectionChanged
?@JonB said in Selection change on key press in QTreeView:
Separate question from why you need even filter at all, not just handle currentChanged/selectionChanged?
I didn't know how to do that :-) But now I figured it out, thanks!
P.S. Changing the order of key press handling in
eventFilter
doesn't seem to have the effect.