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.0k 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.
  • C Creaperdown

    @JonB yeah, I thought about that but decided to post it here since the issue might be on the c++ side of QAbstractItemModel, but I'll move it over there

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

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

    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:

      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