Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Selection change on key press in QTreeView
QtWS25 Last Chance

Selection change on key press in QTreeView

Scheduled Pinned Locked Moved Solved Qt for Python
3 Posts 2 Posters 1.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    midnightdim
    wrote on 3 Mar 2021, 11:36 last edited by
    #1

    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 using eventFilter().

    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_())
    
    J 1 Reply Last reply 3 Mar 2021, 12:33
    0
    • M midnightdim
      3 Mar 2021, 11:36

      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 using eventFilter().

      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_())
      
      J Offline
      J Offline
      JonB
      wrote on 3 Mar 2021, 12:33 last edited by JonB 3 Mar 2021, 12:34
      #2

      @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 your eventFilter() 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?

      M 1 Reply Last reply 3 Mar 2021, 13:51
      1
      • J JonB
        3 Mar 2021, 12:33

        @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 your eventFilter() 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?

        M Offline
        M Offline
        midnightdim
        wrote on 3 Mar 2021, 13:51 last edited by
        #3

        @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.

        1 Reply Last reply
        0

        2/3

        3 Mar 2021, 12:33

        • Login

        • Login or register to search.
        2 out of 3
        • First post
          2/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved