Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. TreeView of QFileSystemModel: Remember selection after sorting
Forum Updated to NodeBB v4.3 + New Features

TreeView of QFileSystemModel: Remember selection after sorting

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 3 Posters 2.6k 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
    maxwell31
    wrote on last edited by
    #1

    Hi,

    I am trying to modify the filesystembrowser example (Qt-Creator -> Welcome -> Examples) to be able to sort by modification date. I did this via adding

    Q_INVOKABLE virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override {
        qDebug("sort by column %d",column);
        QFileSystemModel::sort(column,order);
    }
    

    to DisplayFileSystemModel and setting

    TreeView {
        sortIndicatorVisible: true
    

    The sorting is working, but the selection will just stay at the same index. How should I do it so that the same file/s are still selected (I guess the indices change after the sorting)

    1 Reply Last reply
    0
    • M Offline
      M Offline
      maxwell31
      wrote on last edited by
      #2

      Someone?

      1 Reply Last reply
      0
      • M Offline
        M Offline
        maxwell31
        wrote on last edited by
        #3

        The problem seems to be that the selected indices in QItemSelectionModel do not get updated if I do a sorting of my model. But is there really no functionality in QT which takes care of this?

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          connect a slot to QAbstractItemModel::layoutAboutToBeChanged where you access the QItemSelectionModel::selection(), iterate over all the indexes() and save them in a list of QPersistentModelIndexes

          Then create another slot to QAbstractItemModel::layoutChanged, clear the current selection, iterate over your saved indexes and re-select them

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          2
          • M Offline
            M Offline
            maxwell31
            wrote on last edited by maxwell31
            #5

            @VRonin Thank you for your answer. I think you are right, this is probably how it should be done. Now I am wondering about the following: I store the persistent indices in a

              QList<QPersistentModelIndex> _selectedIndices;
            

            I set it via a Q_INVOKABLE function

            Q_INVOKABLE void setSelected(QModelIndexList list) {
                _selectedIndices.clear();
                for(int i=0;i<list.count();i++) {
                    _selectedIndices.append(QPersistentModelIndex(list[i]));
                }
            }
            

            Now I wonder about how to return it to QML so I don't get type problems

            1 Reply Last reply
            0
            • M Offline
              M Offline
              maxwell31
              wrote on last edited by maxwell31
              #6

              Ok, I should simply use a QVariantList instead of a QList<QPersistentModelIndex>. However, when I want to do the selection again in QML:

                          for(var item in selectionList) {
                              selection.select(item);
                          }
              

              I get the following error:

                qrc:/FileSystem.qml:136: Error: Unable to determine callable overload.  Candidates are:
              select(QItemSelection,QItemSelectionModel::SelectionFlags)
              select(QModelIndex,QItemSelectionModel::SelectionFlags)
              

              Why does it not recognice that the QVariant holds a QModelindex? But maybe I should do it all on the c++ side. However, I wonder how I get the QItemSelectionModel in my model, or how I can connect the QFileSystemModel and the QItemSelectionModel.

              JonBJ 1 Reply Last reply
              0
              • M maxwell31

                Ok, I should simply use a QVariantList instead of a QList<QPersistentModelIndex>. However, when I want to do the selection again in QML:

                            for(var item in selectionList) {
                                selection.select(item);
                            }
                

                I get the following error:

                  qrc:/FileSystem.qml:136: Error: Unable to determine callable overload.  Candidates are:
                select(QItemSelection,QItemSelectionModel::SelectionFlags)
                select(QModelIndex,QItemSelectionModel::SelectionFlags)
                

                Why does it not recognice that the QVariant holds a QModelindex? But maybe I should do it all on the c++ side. However, I wonder how I get the QItemSelectionModel in my model, or how I can connect the QFileSystemModel and the QItemSelectionModel.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @maxwell31
                Assuming QML compiler is no different than a prog lang compiler like C++, why should it? Each item in a QVariantList is a QVariant. They don't do code analysis :) You will need one of the cast<> constructs, or similar, I presume.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  maxwell31
                  wrote on last edited by maxwell31
                  #8

                  @JonB: Do you know how this can be done in QML? (I am calling the method from QML).

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    maxwell31
                    wrote on last edited by
                    #9

                    Hm, actually yes, I can use the conversion functions from QVariant.

                    Regarding my above error: The problem was I did not supply ItemSelectionModel.Select as the second argument

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      maxwell31
                      wrote on last edited by
                      #10

                      @VRonin : You suggested I should access QItemSelectionModel in c++, how can this be done, if the QItemSelectionModel has only been attached to the view and not the model?

                      VRoninV 1 Reply Last reply
                      0
                      • M maxwell31

                        @VRonin : You suggested I should access QItemSelectionModel in c++, how can this be done, if the QItemSelectionModel has only been attached to the view and not the model?

                        VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #11

                        @maxwell31 I was thinking of something like:

                        class SelectionSaver : public QObject
                        Q_OBJECT
                        Q_DISABLE_COPY(SelectionSaver)
                        public:
                        explicit SelectionSaver(QObject* parent = nullptr) : QObject(parent){}
                        private:
                        QVector<QPersistentModelIndex> m_indexList;
                        public Q_SLOTS:
                        void storeSelection(const QModelIndexList& sel){
                        m_indexList.clear();
                        m_indexList.reserve(sel.size());
                        for(auto&& idx : sel)
                        m_indexList.append(idx);
                        }
                        void restoreSelection(QItemSelectionModel* selModel){
                        QItemSelection newSelection;
                        for(auto&& idx : qAsConst(m_indexList))
                        newSelection.select(idx,idx);
                        selModel->select(newSelection,QItemSelectionModel::ClearAndSelect);
                        m_indexList.clear();
                        }
                        };
                        

                        Then from QML you call storeSelection passing TreeView.selection. selectedIndexes and then call restoreSelection passing TreeView.selection

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        2
                        • M Offline
                          M Offline
                          maxwell31
                          wrote on last edited by
                          #12

                          @VRonin Thanks a lot! I did not now that one can simply pass pointers of the objects from QML. However, for some reason it is not working yet. I will report on this tomorrow.

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            maxwell31
                            wrote on last edited by
                            #13

                            Yes, it works now. However, in restoreSelection you need to do

                                      selModel->clearSelection();
                            

                            before selModel->select. Not sure why, but otherwise the new selection is not shown.

                            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