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. ListView delegate isnt able to access model properties after inserting into QAbstractItemModel
Qt 6.11 is out! See what's new in the release blog

ListView delegate isnt able to access model properties after inserting into QAbstractItemModel

Scheduled Pinned Locked Moved Solved General and Desktop
23 Posts 5 Posters 3.1k 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.
  • Christian EhrlicherC Christian Ehrlicher

    @Creaperdown said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

    it here since the issue might be on the c++ side of QAbstractItemModel

    If so why don't you show us your model implementation?

    C Offline
    C Offline
    Creaperdown
    wrote on last edited by Creaperdown
    #5

    @Christian-Ehrlicher good point, here it is:

    class ADAPTERS_EXPORT BookmarksModel : public QAbstractListModel
    {
        Q_OBJECT
    
    public:
        enum Roles
        {
            UuidRole = Qt::UserRole,
            NameRole,
            PageNumberRole,
            YOffsetRole
        };
    
        BookmarksModel(const QList<domain::entities::Bookmark>& data);
    
        int rowCount(const QModelIndex& parent) const override;
        QVariant data(const QModelIndex& index, int role) const override;
        QHash<int, QByteArray> roleNames() const override;
    
    public slots:
        void startInsertingBookmark(int index);
        void endInsertingBookmark();
        void startDeletingBookmark(int index);
        void endDeletingBookmark();
        void bookmarkNameChanged(int row);
    
    private:
        const QList<domain::entities::Bookmark> m_data;
    };
    

    cpp:

    BookmarksModel::BookmarksModel(const QList<domain::entities::Bookmark>& data) :
        m_data(data)
    {
    }
    
    int BookmarksModel::rowCount(const QModelIndex& parent) const
    {
        if(parent.isValid())
            return 0;
    
        return m_data.size();
    }
    
    QVariant BookmarksModel::data(const QModelIndex& index, int role) const
    {
        if(!index.isValid())
            return QVariant();
    
        const Bookmark& bookmark = m_data.at(index.row());
        switch(role)
        {
        case UuidRole:
            return bookmark.getUuid();
        case NameRole:
            return bookmark.getName();
        case PageNumberRole:
            return bookmark.getPageNumber();
        case YOffsetRole:
            return bookmark.getYOffset();
        default:
            return QVariant();
        }
    }
    
    QHash<int, QByteArray> BookmarksModel::roleNames() const
    {
        static QHash<int, QByteArray> roles {
    
            { UuidRole, "uuid" },
            { NameRole, "name" },
            { PageNumberRole, "pageNumber" },
            { YOffsetRole, "yOffset" },
        };
    
        return roles;
    }
    
    void BookmarksModel::startInsertingBookmark(int index)
    {
        beginInsertRows(QModelIndex(), index, index);
    }
    
    void BookmarksModel::endInsertingBookmark()
    {
        endInsertRows();
    }
    
    void BookmarksModel::startDeletingBookmark(int index)
    {
        beginRemoveRows(QModelIndex(), index, index);
    }
    
    void BookmarksModel::endDeletingBookmark()
    {
        endRemoveRows();
    }
    
    void BookmarksModel::bookmarkNameChanged(int row)
    {
        emit dataChanged(index(row, 0), index(row, 0), { NameRole });
    }
    

    The bookmarks are added from another class, that is emitting signals that are connected to the public slots like startInsertingRow, ... I have checked the connections and they are triggered correctly.

    Christian EhrlicherC 1 Reply Last reply
    0
    • C Offline
      C Offline
      Creaperdown
      wrote on last edited by
      #6

      This is how a bookmark is added:

         auto book = getBook();
      
          emit bookmarkInsertionStarted(book->getBookmarks().count());
          book->addBookmark(bookmark);
          emit bookmarkInsertionEnded();
      

      and here you can see that these signals are connected to the slots:

      connect(m_bookService, &application::IBookService::bookmarkInsertionStarted,
                  m_bookmarksModel.get(),
                  &data_models::BookmarksModel::startInsertingBookmark);
      
          connect(m_bookService, &application::IBookService::bookmarkInsertionEnded,
                  m_bookmarksModel.get(),
                  &data_models::BookmarksModel::endInsertingBookmark);
      
      1 Reply Last reply
      0
      • C Offline
        C Offline
        Creaperdown
        wrote on last edited by
        #7

        I am exposing a SortFilterProxyModel with my BookmarksModel set as the source, but I do not think that this should cause any problems.

        1 Reply Last reply
        0
        • C Creaperdown

          @Christian-Ehrlicher good point, here it is:

          class ADAPTERS_EXPORT BookmarksModel : public QAbstractListModel
          {
              Q_OBJECT
          
          public:
              enum Roles
              {
                  UuidRole = Qt::UserRole,
                  NameRole,
                  PageNumberRole,
                  YOffsetRole
              };
          
              BookmarksModel(const QList<domain::entities::Bookmark>& data);
          
              int rowCount(const QModelIndex& parent) const override;
              QVariant data(const QModelIndex& index, int role) const override;
              QHash<int, QByteArray> roleNames() const override;
          
          public slots:
              void startInsertingBookmark(int index);
              void endInsertingBookmark();
              void startDeletingBookmark(int index);
              void endDeletingBookmark();
              void bookmarkNameChanged(int row);
          
          private:
              const QList<domain::entities::Bookmark> m_data;
          };
          

          cpp:

          BookmarksModel::BookmarksModel(const QList<domain::entities::Bookmark>& data) :
              m_data(data)
          {
          }
          
          int BookmarksModel::rowCount(const QModelIndex& parent) const
          {
              if(parent.isValid())
                  return 0;
          
              return m_data.size();
          }
          
          QVariant BookmarksModel::data(const QModelIndex& index, int role) const
          {
              if(!index.isValid())
                  return QVariant();
          
              const Bookmark& bookmark = m_data.at(index.row());
              switch(role)
              {
              case UuidRole:
                  return bookmark.getUuid();
              case NameRole:
                  return bookmark.getName();
              case PageNumberRole:
                  return bookmark.getPageNumber();
              case YOffsetRole:
                  return bookmark.getYOffset();
              default:
                  return QVariant();
              }
          }
          
          QHash<int, QByteArray> BookmarksModel::roleNames() const
          {
              static QHash<int, QByteArray> roles {
          
                  { UuidRole, "uuid" },
                  { NameRole, "name" },
                  { PageNumberRole, "pageNumber" },
                  { YOffsetRole, "yOffset" },
              };
          
              return roles;
          }
          
          void BookmarksModel::startInsertingBookmark(int index)
          {
              beginInsertRows(QModelIndex(), index, index);
          }
          
          void BookmarksModel::endInsertingBookmark()
          {
              endInsertRows();
          }
          
          void BookmarksModel::startDeletingBookmark(int index)
          {
              beginRemoveRows(QModelIndex(), index, index);
          }
          
          void BookmarksModel::endDeletingBookmark()
          {
              endRemoveRows();
          }
          
          void BookmarksModel::bookmarkNameChanged(int row)
          {
              emit dataChanged(index(row, 0), index(row, 0), { NameRole });
          }
          

          The bookmarks are added from another class, that is emitting signals that are connected to the public slots like startInsertingRow, ... I have checked the connections and they are triggered correctly.

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #8

          @Creaperdown said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

          void BookmarksModel::startInsertingBookmark(int index)
          {
          beginInsertRows(QModelIndex(), index, index);
          }

          void BookmarksModel::endInsertingBookmark()
          {
          endInsertRows();
          }

          void BookmarksModel::startDeletingBookmark(int index)
          {
          beginRemoveRows(QModelIndex(), index, index);
          }

          void BookmarksModel::endDeletingBookmark()
          {
          endRemoveRows();
          }

          Imo this should not be exposed to the outside. Write a custom function in your model which adds/removes a bookmark and call begin/endFoo() in there. Otherwise the user of your model must know that he needs to call startInsertingBookmark() / endInsertBookmark() for every inserted bookmark. Also I don't see a function which really adds something to the model.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          C 1 Reply Last reply
          0
          • SGaistS SGaist referenced this topic on
          • Christian EhrlicherC Christian Ehrlicher

            @Creaperdown said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

            void BookmarksModel::startInsertingBookmark(int index)
            {
            beginInsertRows(QModelIndex(), index, index);
            }

            void BookmarksModel::endInsertingBookmark()
            {
            endInsertRows();
            }

            void BookmarksModel::startDeletingBookmark(int index)
            {
            beginRemoveRows(QModelIndex(), index, index);
            }

            void BookmarksModel::endDeletingBookmark()
            {
            endRemoveRows();
            }

            Imo this should not be exposed to the outside. Write a custom function in your model which adds/removes a bookmark and call begin/endFoo() in there. Otherwise the user of your model must know that he needs to call startInsertingBookmark() / endInsertBookmark() for every inserted bookmark. Also I don't see a function which really adds something to the model.

            C Offline
            C Offline
            Creaperdown
            wrote on last edited by
            #9

            @Christian-Ehrlicher I have written a second reply, containing the function that adds the bookmark.

            Does moving the functions into the model make a difference functionality wise? Using the signal-approach should be doing exactly the same, shouldn't it?
            I am using this approach throughout my application to separate the code responsible for the qml representation from the actual logic.

            I'll consider moving it into the models, but for now I'd prefer to solve it this way, if it isn't the root of the problem.

            Christian EhrlicherC 1 Reply Last reply
            0
            • C Creaperdown

              @Christian-Ehrlicher I have written a second reply, containing the function that adds the bookmark.

              Does moving the functions into the model make a difference functionality wise? Using the signal-approach should be doing exactly the same, shouldn't it?
              I am using this approach throughout my application to separate the code responsible for the qml representation from the actual logic.

              I'll consider moving it into the models, but for now I'd prefer to solve it this way, if it isn't the root of the problem.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #10

              @Creaperdown said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

              oes moving the functions into the model make a difference functionality wise? Using the signal-approach should be doing exactly the same, shouldn't it?

              Yes, but the user of your model must know to call begin/endFoo() for no reason - can be done directly in addBookmark() and nothing can go wrong then like e.g.:

              emit bookmarkInsertionStarted(book->getBookmarks().count());
              book->addBookmark(bookmark);
              book->addBookmark(bookmark);
              emit bookmarkInsertionEnded();
              

              or

              emit bookmarkInsertionStarted(book->getBookmarks().count());
              emit bookmarkInsertionEnded();
              

              which can be easily avoided.

              But that's not the your current issue, just a bad desgin (imo).

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              C 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @Creaperdown said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

                oes moving the functions into the model make a difference functionality wise? Using the signal-approach should be doing exactly the same, shouldn't it?

                Yes, but the user of your model must know to call begin/endFoo() for no reason - can be done directly in addBookmark() and nothing can go wrong then like e.g.:

                emit bookmarkInsertionStarted(book->getBookmarks().count());
                book->addBookmark(bookmark);
                book->addBookmark(bookmark);
                emit bookmarkInsertionEnded();
                

                or

                emit bookmarkInsertionStarted(book->getBookmarks().count());
                emit bookmarkInsertionEnded();
                

                which can be easily avoided.

                But that's not the your current issue, just a bad desgin (imo).

                C Offline
                C Offline
                Creaperdown
                wrote on last edited by
                #11

                @Christian-Ehrlicher thanks for the recommendation, I'll be looking into that but I'm still not sure what causes me actual issue

                Christian EhrlicherC 1 Reply Last reply
                0
                • C Creaperdown

                  @Christian-Ehrlicher thanks for the recommendation, I'll be looking into that but I'm still not sure what causes me actual issue

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #12

                  @Creaperdown There I can't help - don't use QML

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  C 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @Creaperdown There I can't help - don't use QML

                    C Offline
                    C Offline
                    Creaperdown
                    wrote on last edited by
                    #13

                    @Christian-Ehrlicher So you think this is a qml related problem?

                    Christian EhrlicherC JonBJ 2 Replies Last reply
                    0
                    • C Creaperdown

                      @Christian-Ehrlicher So you think this is a qml related problem?

                      Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #14

                      I would create a single/atomar add function to really make sure the add is correct but the rest looks good.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      0
                      • C Creaperdown

                        @Christian-Ehrlicher So you think this is a qml related problem?

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

                        @Creaperdown
                        Yes indeed it is, which is why I suggested this thread might be better moved to QML forum in the first place, though never mind now.

                        C 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @Creaperdown
                          Yes indeed it is, which is why I suggested this thread might be better moved to QML forum in the first place, though never mind now.

                          C Offline
                          C Offline
                          Creaperdown
                          wrote on last edited by
                          #16

                          @JonB I'll be closing this here then and moving it to the Qml section

                          Christian EhrlicherC JoeCFDJ 2 Replies Last reply
                          0
                          • C Creaperdown deleted this topic on
                          • C Creaperdown

                            @JonB I'll be closing this here then and moving it to the Qml section

                            Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #17

                            Why do you delete this thread? To start over the same discussion about the possible wrong usage of begin/endInsertRows again?

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            1 Reply Last reply
                            0
                            • Christian EhrlicherC Christian Ehrlicher restored this topic on
                            • C Creaperdown

                              @JonB I'll be closing this here then and moving it to the Qml section

                              JoeCFDJ Offline
                              JoeCFDJ Offline
                              JoeCFD
                              wrote on last edited by
                              #18

                              @Creaperdown in your model, do the following:

                                  beginResetModel();
                                   add new row()
                                  endResetModel();
                              
                              SGaistS 1 Reply Last reply
                              0
                              • JoeCFDJ JoeCFD

                                @Creaperdown in your model, do the following:

                                    beginResetModel();
                                     add new row()
                                    endResetModel();
                                
                                SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #19

                                @JoeCFD said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

                                @Creaperdown in your model, do the following:

                                    beginResetModel();
                                     add new row()
                                    endResetModel();
                                

                                If you need to reset the whole model because you insert one row, there's likely a design issue.

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

                                JoeCFDJ 1 Reply Last reply
                                0
                                • SGaistS SGaist

                                  @JoeCFD said in ListView delegate isnt able to access model properties after inserting into QAbstractItemModel:

                                  @Creaperdown in your model, do the following:

                                      beginResetModel();
                                       add new row()
                                      endResetModel();
                                  

                                  If you need to reset the whole model because you insert one row, there's likely a design issue.

                                  JoeCFDJ Offline
                                  JoeCFDJ Offline
                                  JoeCFD
                                  wrote on last edited by
                                  #20

                                  @SGaist It is an option. I am not sure if everything is redone.

                                  SGaistS 1 Reply Last reply
                                  0
                                  • JoeCFDJ JoeCFD

                                    @SGaist It is an option. I am not sure if everything is redone.

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

                                    @JoeCFD basically, it tells the view that everything has changed so it should reload everything as a consequence.

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

                                    JoeCFDJ 1 Reply Last reply
                                    1
                                    • SGaistS SGaist

                                      @JoeCFD basically, it tells the view that everything has changed so it should reload everything as a consequence.

                                      JoeCFDJ Offline
                                      JoeCFDJ Offline
                                      JoeCFD
                                      wrote on last edited by JoeCFD
                                      #22

                                      @SGaist True. kind of global update. It is better to use
                                      beginInsertRows() and endInsertRows().

                                      1 Reply Last reply
                                      0
                                      • C Offline
                                        C Offline
                                        Creaperdown
                                        wrote on last edited by
                                        #23

                                        The problem was a missing reference on the container. It should have been QList<Bookmark>&, thus it didnt update the container when I add a book.

                                        1 Reply Last reply
                                        0
                                        • C Creaperdown has marked this topic as solved on

                                        • Login

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