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
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Solved General and Desktop
23 Posts 5 Posters 2.3k 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 Offline
    C Offline
    Creaperdown
    wrote on last edited by Creaperdown
    #1

    I have a QAbstractItemModel that I am exposing to Qml to display. When inserting a new item into it, I properly call the beginInsertRows(QModelIndex(), index, index); and endInsertRows(); functions. The item gets inserted correctly, but my delegate (in a ListView):

    delegate: Rectangle {
                            width: bookmarksView.width
                            height: 24
                            color: "red"
                            opacity: 0.5
    
                            Label {
                                id: bookmarkName
                                anchors.centerIn: parent
                                text: model.name
                                color: Style.colorText
                                font.pointSize: 11
                            }
                        }
    

    gives me an error that it cant assign unkown to QString on the line text: model.name, but after reloading the page it works fine. So it just isnt able to access it right after I have inserted the new item.

    Does someone have an idea why this happens?

    JonBJ 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

        I have a QAbstractItemModel that I am exposing to Qml to display. When inserting a new item into it, I properly call the beginInsertRows(QModelIndex(), index, index); and endInsertRows(); functions. The item gets inserted correctly, but my delegate (in a ListView):

        delegate: Rectangle {
                                width: bookmarksView.width
                                height: 24
                                color: "red"
                                opacity: 0.5
        
                                Label {
                                    id: bookmarkName
                                    anchors.centerIn: parent
                                    text: model.name
                                    color: Style.colorText
                                    font.pointSize: 11
                                }
                            }
        

        gives me an error that it cant assign unkown to QString on the line text: model.name, but after reloading the page it works fine. So it just isnt able to access it right after I have inserted the new item.

        Does someone have an idea why this happens?

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

        @Creaperdown Might be better if this is posted to https://forum.qt.io/category/12/qml-and-qt-quick category.

        C 1 Reply Last reply
        0
        • JonBJ JonB

          @Creaperdown Might be better if this is posted to https://forum.qt.io/category/12/qml-and-qt-quick category.

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

          @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 1 Reply Last reply
          0
          • 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 Online
            Christian EhrlicherC Online
            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 Online
                    Christian EhrlicherC Online
                    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 Online
                        Christian EhrlicherC Online
                        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 Online
                            Christian EhrlicherC Online
                            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 Online
                                Christian EhrlicherC Online
                                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 Online
                                  JonBJ Online
                                  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 Online
                                      Christian EhrlicherC Online
                                      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

                                            • Login

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