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. [SOLVED] QPersistentModelIndex usage
QtWS25 Last Chance

[SOLVED] QPersistentModelIndex usage

Scheduled Pinned Locked Moved General and Desktop
24 Posts 2 Posters 15.7k 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.
  • K Offline
    K Offline
    Kobid
    wrote on last edited by
    #1

    Hi.

    I have own directory model based on QAbstractItemModel (I just copied TreeModel example and modified to my needs). This is my structure:

    @class HCDirItem
    {
    public:
    explicit HCDirItem(HCDirItem *parent = 0);
    ~HCDirItem();

    void appendChild(HCDirItem *child);
    void removeChild(HCDirItem *child);
    
    HCDirItem *child(int row);
    int childCount() const;
    int row() const;
    HCDirItem *parent();
    
    void clear();
    

    private:
    QList<HCDirItem*> childItems;
    HCDirItem *parentItem;
    };

    class HCDirModel : public QAbstractItemModel
    {
    Q_OBJECT

    public:
    explicit HCDirModel(QObject *parent = 0);
    ~HCDirModel();
    HCDirItem *rootItem;

    QVariant data(const QModelIndex &index, int role) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const;
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const;
    QModelIndex parent(const QModelIndex &index) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    void loadTree(const QString &rootdir);
    void clear();
    HCDirItem *at(const QModelIndex &index);
    const QHash<QString, HCDirItem*> *items();
    HCDirItem *find(const QString &path);
    HCDirItem *addFolder(const QString &path);
    bool deleteFolder(const QString &path);
    

    private:
    QHash<QString, HCDirItem*> mItems;
    };@

    My application getting notifications that some file changed. I need to find it in my tree and update (or delete). As you can see I have QHash<QString, HCDirItem*> mItems so I can do quick lookup. So I know how to find HCDirItem but don't know how to get its index for emit dataChanged(QModelIndex...). I found that I should use QPersistentModelIndex but can't find any example how and where to create it

    1 Reply Last reply
    0
    • raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      just pass your QModelIndex to the constructor of QPersistentModelIndex and your good to go.

      You then can save the QPersistentModelIndex. And don't forget to check for validity of the persistent index every time you use it.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • K Offline
        K Offline
        Kobid
        wrote on last edited by
        #3

        Yes but I don't know how to create QModelIndex for current changed item. For example, lets say that I have this tree:

        @-A (0,0)
        |-D (0,0)
        |-E (1,0)
        -B (1,0)
        -C (2,0)@

        Now I want to add new item between D and E.

        1. I know that the parent HCDirItem is A
        2. I'm creating new instance F of HCDirItem and appending it to the parent by calling A.appendChild(F)
        3. Now I need to create QModelIndex for QPersistentModelIndex. index() function need 3 arguments, I know which row (1) and column (0) it is. But third arguments is parent QModelIndex and I don't know what to set here
        1 Reply Last reply
        0
        • raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          the parent is the QModelIndex of A.
          And if it's a top level item, then the parent is a invalid QModelIndex()

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • K Offline
            K Offline
            Kobid
            wrote on last edited by
            #5

            I still don't understand :P . Ok more complicated example:

            @A
            |- B
            |- C
            |- D@

            Now if I want to create QModelIndex for D as third example I need QModelindex of C but to create index for C I need parent of C which is B etc. I need enumerate all parents to get index for D?

            1 Reply Last reply
            0
            • raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              yes ... or you use the parent() of a already known index

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • K Offline
                K Offline
                Kobid
                wrote on last edited by
                #7

                So can I just create public QModelIndex index variable in HCDirItem object and setup it when item is created? Because I don't see difference between QModelIndex and QPersistentModelIndex

                1 Reply Last reply
                0
                • raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  the difference is that the QPersistentIndex gets automatically invalid when the QModelIndex gets invalid (when they do not point to valid data anymore in the model). QModelIndexes don't.
                  Think of it like QPointer for ordinary pointers.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    Kobid
                    wrote on last edited by
                    #9

                    Thanks! Now it is working perfect! I'm just wondering how it is working. For example. Each item is holding QPersistentModelIndex of its self. Now if I have this list:

                    aaaa
                    bbbb
                    cccc

                    QList is holding these items. Now when I add new item

                    aaaa
                    bbbb
                    cccc
                    abc

                    ... it has QPersistentModelIndex (3,0). Same for QModelIndex. If I sort QList using qSort then list looks like:

                    aaaa
                    abc
                    bbbb
                    cccc

                    abc still has QPersistentModelIndex (3,0) but QTreeView.currentIndex is (1,0).

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      Kobid
                      wrote on last edited by
                      #10

                      Last question. Can I use QPersistenModelIndex to build normal index? For example: I know that data in known QPersistenModelIndex changed. I need to emit dataChanged. My QPersistenModelIndex always point to first (0) column but I want to update whole row, so I need to create second index as "to" and point to the last column. Can I use QPersistenModelIndex.row() for "to" in QModelIndex? I'm confused because QPersistenModelIndex.row() point to old row after sorting.

                      1 Reply Last reply
                      0
                      • raven-worxR Offline
                        raven-worxR Offline
                        raven-worx
                        Moderators
                        wrote on last edited by
                        #11

                        how do you sort? Using a QSortFilterProxyModel? Or in a custom model?

                        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                        If you have a question please use the forum so others can benefit from the solution in the future

                        1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          Kobid
                          wrote on last edited by
                          #12

                          No, I'm using qSort on QList<HCFileItem>

                          1 Reply Last reply
                          0
                          • raven-worxR Offline
                            raven-worxR Offline
                            raven-worx
                            Moderators
                            wrote on last edited by
                            #13

                            and are you sure you are triggering the right signals of the model to inform about the model change?

                            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                            If you have a question please use the forum so others can benefit from the solution in the future

                            1 Reply Last reply
                            0
                            • K Offline
                              K Offline
                              Kobid
                              wrote on last edited by
                              #14

                              I think so:

                              @emit layoutAboutToBeChanged();
                              qSort(childItems.begin(), childItems.end(), compareFilenameA);
                              emit layoutChanged();@

                              1 Reply Last reply
                              0
                              • raven-worxR Offline
                                raven-worxR Offline
                                raven-worx
                                Moderators
                                wrote on last edited by
                                #15

                                try "QAbstractItemModel::dataChanged()":http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#dataChanged
                                If it doesn't make a difference you can also try "QAbstractItemModel::changePersistentIndex()":http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#changePersistentIndex

                                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                If you have a question please use the forum so others can benefit from the solution in the future

                                1 Reply Last reply
                                0
                                • K Offline
                                  K Offline
                                  Kobid
                                  wrote on last edited by
                                  #16

                                  Same result. My model is sorted correctly but QPersistenModelIndex.row() has old value. Don't know if it's ok

                                  1 Reply Last reply
                                  0
                                  • raven-worxR Offline
                                    raven-worxR Offline
                                    raven-worx
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    before further investigating i would recommend that you try "ModelTest":http://qt-project.org/wiki/Model_Test to make sure your model is implemented correctly.

                                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                    If you have a question please use the forum so others can benefit from the solution in the future

                                    1 Reply Last reply
                                    0
                                    • K Offline
                                      K Offline
                                      Kobid
                                      wrote on last edited by
                                      #18

                                      Ehh, can't adjust ModelTest to my model. There are really missing example of QPersistentModelIndex usage. Summarizing, my model is working ok, but don't know why :P . I have this structure:

                                      @struct HCFileItem {
                                      QPersistentModelIndex persistentIndex;
                                      };

                                      class HCFileModel: public QAbstractItemModel
                                      {
                                      Q_OBJECT
                                      public:
                                      explicit HCFileModel(QObject parent=0);
                                      ~HCFileModel();
                                      protected:
                                      QList<HCFileItem
                                      > *mList=0;
                                      };@

                                      Example:

                                      My model contain one item:

                                      "bbbb"

                                      Now I'm inserting (using beginInsertRows) item "aaaa" and my persistent indexes looks like:

                                      "bbbb" (0,0)
                                      "aaaa" (1,0)

                                      Now I'm sorting my model using qSort on mList and emitting signal dataChanged(firstIndex, secondIndex). After this my persistent indexes looks like:

                                      "aaaa" (1,0)
                                      "bbbb" (0,0)

                                      But it works, if I change data in "aaaa" and emit signal dataChanged with saved persistent index in HCFileItem then correct item is refreshed even if QPersistentModelIndex.row() point to wrong row. I'm confused

                                      1 Reply Last reply
                                      0
                                      • raven-worxR Offline
                                        raven-worxR Offline
                                        raven-worx
                                        Moderators
                                        wrote on last edited by
                                        #19

                                        using ModelTest is as easy (nothing to adjust at all) as:
                                        @
                                        HCFileModel* model = new HCFileModel(parent);
                                        new ModelTest(model, parent);
                                        @
                                        If your model has an error in any state while you use it an assertion will trigger and give you info what went wrong.

                                        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                        If you have a question please use the forum so others can benefit from the solution in the future

                                        1 Reply Last reply
                                        0
                                        • K Offline
                                          K Offline
                                          Kobid
                                          wrote on last edited by
                                          #20

                                          Ok my model pass test. So I have no idea why QPersistentModelIndex row() has old value after sort. But everything work, IsValid return True. Must check on QStandardItemModel and QSortFilterProxyModel if persistent index will keep old row too

                                          1 Reply Last reply
                                          0

                                          • Login

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