Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Treeview + QFileSystemModel, how can i retrieve multi selection list
Forum Updated to NodeBB v4.3 + New Features

Treeview + QFileSystemModel, how can i retrieve multi selection list

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 2.8k Views 2 Watching
  • 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.
  • B blossomsg

    Hey @Gojir4 ,

    Yes i did

    	self.treeview.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
    

    so selection works fine, after the selection i want to query all the highlighted selections
    and pyside2 should return me object or str or unicode, so through that i can extract exact path of all the highlighted items

    Gojir4G Offline
    Gojir4G Offline
    Gojir4
    wrote on last edited by Gojir4
    #4

    @blossomsg I'm not sure to understand what is the problem here. anyway here is a small example using signal selectionChanged from QItemSelectionModel.

    from PySide2.QtWidgets import QTreeView, QAbstractItemView, QApplication
    from PySide2.QtGui import QStandardItemModel, QStandardItem
    from PySide2.QtCore import Qt, QObject, QItemSelectionModel
    import sys
    
    a = QApplication(sys.argv)
    
    tree = QTreeView()
    model = QStandardItemModel(tree)
    tree.setModel(model)
    tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
    
    row = QStandardItem('Row 1')
    model.appendRow(row)
    row.appendRow(QStandardItem('Row 1 1'))
    row.appendRow(QStandardItem('Row 1 2'))
    row = QStandardItem('Row 2')
    model.appendRow(row)
    row.appendRow(QStandardItem('Row 2 1'))
    row.appendRow(QStandardItem('Row 2 2'))
    model.appendRow(QStandardItem('Row 3'))
    model.appendRow(QStandardItem('Row 4'))
    
    selectionModel: QItemSelectionModel = tree.selectionModel()
    def selectionChanged(selected, deselected):
        print('selected: {}'.format(','.join(str(i.row()) for i in selected.indexes())))
        # Displaying Row index 
        print('full selection: {}'.format(','.join(str(i.row()) for i in selectionModel.selectedIndexes())))
        # Displaying data
        print('full selection text: {}'.format(','.join(str(i.data()) for i in selectionModel.selectedIndexes())))
    
    selectionModel.selectionChanged.connect(selectionChanged)
    
    tree.show()
    a.exec_()
    
    1 Reply Last reply
    0
    • B Offline
      B Offline
      blossomsg
      wrote on last edited by
      #5

      Hey Thanks for the snippet @Gojir4 ,
      the extended selection works fine, but if now i want to print every item that i have selected randomly how can i do that?

      eg:
      D:/
      a
      b
      c
      e
      f

      so then if i select a, c, e, f-- how can i return selection values of all four items as strings
      any approach?

      Gojir4G 1 Reply Last reply
      0
      • B blossomsg

        Hey Thanks for the snippet @Gojir4 ,
        the extended selection works fine, but if now i want to print every item that i have selected randomly how can i do that?

        eg:
        D:/
        a
        b
        c
        e
        f

        so then if i select a, c, e, f-- how can i return selection values of all four items as strings
        any approach?

        Gojir4G Offline
        Gojir4G Offline
        Gojir4
        wrote on last edited by
        #6

        @blossomsg Using i.data() instead of i.row()

        I have updated my previous post to display data. Note with QFileSystemModel you probably need to use QFileSystemModel.FilePathRole role instead of default Qt.DisplayRole. see https://doc.qt.io/qt-5/qfilesystemmodel.html#Roles-enum

        So instead of i.data(), it will be i.data(QtWidgets.QFileSystemModel.FilePathRole)

        def selectionChanged(selected, deselected):
            ...
            # Displaying Row index 
            print('full selection: {}'.format(','.join(str(i.row()) for i in selectionModel.selectedIndexes())))
            # Displaying data
            print('full selection text: {}'.format(','.join(str(i.data()) for i in selectionModel.selectedIndexes())))
        

        Outputs:

        full selection: 1,2,0,1
        full selection text: Row 2,Row 3,Row 2 1,Row 2 2
        

        For converting list of QModelIndex to string list:

        stringlist = [str(i.data()) for i in selectionModel.selectedIndexes()]
        # or simpler
        stringlist = []
        for i in selectionModel.selectedIndexes():
            stringlist.append(str(i.data()))
        
        1 Reply Last reply
        0
        • B Offline
          B Offline
          blossomsg
          wrote on last edited by
          #7

          Hey @Gojir4 ,

          This is nearly what i want, i just don't understand one line
          this some override

          selectionModel: QItemSelectionModel = tree.selectionModel()

          is this python3, or only pyside2

          can you explain, as i have not come across this approach

          JonBJ 1 Reply Last reply
          0
          • B blossomsg

            Hey @Gojir4 ,

            This is nearly what i want, i just don't understand one line
            this some override

            selectionModel: QItemSelectionModel = tree.selectionModel()

            is this python3, or only pyside2

            can you explain, as i have not come across this approach

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by JonB
            #8

            @blossomsg
            selectionModel: QItemSelectionModel = tree.selectionModel()

            I haven't used it myself, but I believe in later Python 3 you can (optionally) write : type-specification when you create a variable. I use the : type-specification only for the parameters received by methods. This is not a PySide2 thing.

            If you don't like it, or your Python doesn't, it should be just:
            selectionModel = tree.selectionModel()

            It only affects the reading/editing experience anyway, has no effect at runtime.

            Gojir4G 1 Reply Last reply
            1
            • JonBJ JonB

              @blossomsg
              selectionModel: QItemSelectionModel = tree.selectionModel()

              I haven't used it myself, but I believe in later Python 3 you can (optionally) write : type-specification when you create a variable. I use the : type-specification only for the parameters received by methods. This is not a PySide2 thing.

              If you don't like it, or your Python doesn't, it should be just:
              selectionModel = tree.selectionModel()

              It only affects the reading/editing experience anyway, has no effect at runtime.

              Gojir4G Offline
              Gojir4G Offline
              Gojir4
              wrote on last edited by
              #9

              @JonB Exact
              @blossomsg That's only for my editor knowing the type and providing auto-completion, sry for confusion

              JonBJ 1 Reply Last reply
              1
              • Gojir4G Gojir4

                @JonB Exact
                @blossomsg That's only for my editor knowing the type and providing auto-completion, sry for confusion

                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by
                #10

                @Gojir4
                No need to apologise, it's good style. The last time I first looked at Python at Python 3.something-less-than-7/6/5??, it had the : type for method parameters, and the -> type for returns, but not for variables, and it barfed if you tried one. So I wrote all my code using method param types (which personally I highly recommend, but then I like C++ and not Python!), and never could do anything about variables. So that support must have arrived at some more recent Python 3 version? (Or, it's just possible that it was PyCharm which didn't yet understand it, but I thought I saw it only arrived in a recent Python 3?)

                1 Reply Last reply
                1
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #11

                  Hi,

                  Type hinting has been introduced in Python 3.5.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  JonBJ 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    Hi,

                    Type hinting has been introduced in Python 3.5.

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by JonB
                    #12

                    @SGaist
                    Indeed. In 3.5 "type annotations of function parameters, a.k.a. type hints". But the line in @Gojir4 code:

                    selectionModel: QItemSelectionModel = tree.selectionModel()
                    

                    is variable type-hinting. And I believe that did not come till Python 3.6, see https://stackoverflow.com/questions/39971929/what-are-variable-annotations-in-python-3-6 and https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-pep526.

                    So I must have started out on 3.5.x.

                    SGaistS Gojir4G 2 Replies Last reply
                    1
                    • JonBJ JonB

                      @SGaist
                      Indeed. In 3.5 "type annotations of function parameters, a.k.a. type hints". But the line in @Gojir4 code:

                      selectionModel: QItemSelectionModel = tree.selectionModel()
                      

                      is variable type-hinting. And I believe that did not come till Python 3.6, see https://stackoverflow.com/questions/39971929/what-are-variable-annotations-in-python-3-6 and https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-pep526.

                      So I must have started out on 3.5.x.

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      @JonB You're right. I just read the question as "when did type hinting" come to Python.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      2
                      • JonBJ JonB

                        @SGaist
                        Indeed. In 3.5 "type annotations of function parameters, a.k.a. type hints". But the line in @Gojir4 code:

                        selectionModel: QItemSelectionModel = tree.selectionModel()
                        

                        is variable type-hinting. And I believe that did not come till Python 3.6, see https://stackoverflow.com/questions/39971929/what-are-variable-annotations-in-python-3-6 and https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-pep526.

                        So I must have started out on 3.5.x.

                        Gojir4G Offline
                        Gojir4G Offline
                        Gojir4
                        wrote on last edited by
                        #14

                        @JonB I did start using Python 3.6 and switched quickly to 3.8. Taking inspiration from PySide2 functions declaration it was natural for me to use this type hinting also in the code, without even knowing it was something new :). I agree with your I also use method param types, that's make code more clear and understandable, especially with custom types, and probably also because of ten years of C++ :D.

                        1 Reply Last reply
                        1
                        • B Offline
                          B Offline
                          blossomsg
                          wrote on last edited by
                          #15

                          Hello Guys,

                          Thank you for all your effort especially @Gojir4
                          your snippet was amazing

                          https://stackoverflow.com/questions/21684336/how-to-get-the-index-for-the-filepath-of-a-selected-file-via-qfilesystemmodel

                          and the above link helped me resolve the 4 modelindex values to 1 modelindex --- which results 1 path rather than showing all the 4 column paths

                          from PySide2 import QtCore
                          from PySide2 import QtWidgets
                          from PySide2 import QtGui
                          import sys
                          
                          
                          def selectionChanged(selected, deselected):    
                              index = qtreeview_files.currentIndex()
                              print model.filePath(index)
                          
                          
                          qtreeview_files = QtWidgets.QTreeView()
                          model = QtWidgets.QFileSystemModel()
                          model.setRootPath("")
                          qtreeview_files.setModel(model)
                          qtreeview_files.hideColumn(1)
                          qtreeview_files.hideColumn(2)
                          qtreeview_files.hideColumn(3)
                          qtreeview_files.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
                          selectionModel  = qtreeview_files.selectionModel()
                          win_wid = QtWidgets.QWidget()
                          layout = QtWidgets.QVBoxLayout()
                          layout.addWidget(qtreeview_files)
                          win_wid.setLayout(layout)
                          #win_wid.resize(200, 50)
                          
                          
                          win_wid.show()
                          
                          
                          
                          selectionModel.selectionChanged.connect(selectionChanged)
                          
                          1 Reply Last reply
                          1
                          • B Offline
                            B Offline
                            blossomsg
                            wrote on last edited by
                            #16

                            Sorry for late reply got caught up with some personal work

                            just an updated code.

                            from PySide2 import QtCore
                            from PySide2 import QtWidgets
                            from PySide2 import QtGui
                            import sys
                            import os
                            
                            
                            def selectionChanged(selected, deselected):    
                                index = qtreeview_files.currentIndex()
                                print model.filePath(index)
                            
                            
                            qtreeview_files = QtWidgets.QTreeView()
                            model = QtWidgets.QFileSystemModel()
                            model.setRootPath("")
                            qtreeview_files.setModel(model)
                            qtreeview_files.hideColumn(1)
                            qtreeview_files.hideColumn(2)
                            qtreeview_files.hideColumn(3)
                            qtreeview_files.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
                            selectionModel  = qtreeview_files.selectionModel()
                            win_wid = QtWidgets.QWidget()
                            layout = QtWidgets.QVBoxLayout()
                            layout.addWidget(qtreeview_files)
                            win_wid.setLayout(layout)
                            #win_wid.resize(200, 50)
                            
                            
                            win_wid.show()
                            
                            ##after you confirm the selection run this to get final selection list
                            list_of_sel_files = []
                            all = qtreeview_files.selectedIndexes()
                            for x in all:
                                print model.filePath(x)
                                list_of_sel_files.append(model.filePath(x))
                            ##########################################
                            
                            selectionModel.selectionChanged.connect(selectionChanged)
                            

                            closing ticket

                            1 Reply Last reply
                            1

                            • Login

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