Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Change data on QAbstractItemModel subclass model

Change data on QAbstractItemModel subclass model

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 3 Posters 6.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    m.kuncevicius
    wrote on last edited by
    #3

    I want to update data from c++ side. I tried to write setters for Item class, but when I try to use them an error apiers: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
    m_item.at(i).setDescription(value);
    How to change the internal data the right way?

    E 1 Reply Last reply
    0
    • M m.kuncevicius

      I want to update data from c++ side. I tried to write setters for Item class, but when I try to use them an error apiers: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
      m_item.at(i).setDescription(value);
      How to change the internal data the right way?

      E Offline
      E Offline
      Eeli K
      wrote on last edited by
      #4

      @m.kuncevicius Maybe you tried to do something like

      void Item::setDescription(QString desc) const
      

      In that case you have to remove 'const' because it's a setter and quite logically modifies the 'this' object and therefore can't be a const member function. Using the keyword const like this is meant for the member functions which don't modify the perceived state of the 'this' object. (See e.g. https://isocpp.org/wiki/faq/const-correctness#const-member-fns .)

      M 1 Reply Last reply
      0
      • E Eeli K

        @m.kuncevicius Maybe you tried to do something like

        void Item::setDescription(QString desc) const
        

        In that case you have to remove 'const' because it's a setter and quite logically modifies the 'this' object and therefore can't be a const member function. Using the keyword const like this is meant for the member functions which don't modify the perceived state of the 'this' object. (See e.g. https://isocpp.org/wiki/faq/const-correctness#const-member-fns .)

        M Offline
        M Offline
        m.kuncevicius
        wrote on last edited by
        #5

        @Eeli-K Thank you for answer, but setter is not const.

        E 1 Reply Last reply
        0
        • M m.kuncevicius

          @Eeli-K Thank you for answer, but setter is not const.

          E Offline
          E Offline
          Eeli K
          wrote on last edited by
          #6

          @m.kuncevicius Then you have to give the code, otherwise it's impossible to say where the problem is. The error message refers to a situation where a method is const but the this object is changed in it.

          M 1 Reply Last reply
          0
          • E Eeli K

            @m.kuncevicius Then you have to give the code, otherwise it's impossible to say where the problem is. The error message refers to a situation where a method is const but the this object is changed in it.

            M Offline
            M Offline
            m.kuncevicius
            wrote on last edited by
            #7

            @Eeli-K I just added auto genereted setter. The rest of my code:

            Header:

                void setName(const QString &value);
            

            .cpp

            void Item::setName(const QString &value)
            {
                name = value;
            }
            

            main.cpp

            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            #include <QQmlContext>
            #include "item.h"
            
            int main(int argc, char *argv[])
            {
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                QGuiApplication app(argc, argv);
            
                QQmlApplicationEngine engine;
                auto context = engine.rootContext();
                engine.load(QUrl(QLatin1String("qrc:/main.qml")));
            
                ItemModel itemModel;
            
                itemModel.addItem(Item("Name1", "Description1", "12,25", "113548", 1));
                itemModel.addItem(Item("Name2", "Description2", "22,25", "213548", 2));
                itemModel.addItem(Item("Name3", "Description3", "32,25", "313548", 3));
            
                itemModel.item().at(1).setName("Changed");
            
                context->setContextProperty("itemModel", &itemModel);
            
                return app.exec();
            }
            
            E 1 Reply Last reply
            0
            • M m.kuncevicius

              @Eeli-K I just added auto genereted setter. The rest of my code:

              Header:

                  void setName(const QString &value);
              

              .cpp

              void Item::setName(const QString &value)
              {
                  name = value;
              }
              

              main.cpp

              #include <QGuiApplication>
              #include <QQmlApplicationEngine>
              #include <QQmlContext>
              #include "item.h"
              
              int main(int argc, char *argv[])
              {
                  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                  QGuiApplication app(argc, argv);
              
                  QQmlApplicationEngine engine;
                  auto context = engine.rootContext();
                  engine.load(QUrl(QLatin1String("qrc:/main.qml")));
              
                  ItemModel itemModel;
              
                  itemModel.addItem(Item("Name1", "Description1", "12,25", "113548", 1));
                  itemModel.addItem(Item("Name2", "Description2", "22,25", "213548", 2));
                  itemModel.addItem(Item("Name3", "Description3", "32,25", "313548", 3));
              
                  itemModel.item().at(1).setName("Changed");
              
                  context->setContextProperty("itemModel", &itemModel);
              
                  return app.exec();
              }
              
              E Offline
              E Offline
              Eeli K
              wrote on last edited by
              #8

              @m.kuncevicius
              Please paste the error message here and tell what code line it refers to.

              QList<Item> ItemModel::item() const
              {
                  return m_item;
              }
              

              returns a copy so you can't change the model's item through that. But even if it would return a reference or a pointer the model wouldn't work properly because it wouldn't send signals when items are changed. Write the modifier API in the model class, hide the item completely inside it. Either write something like ItemModel::setName(int index, QString name) or override setData. In the model's code when the model data is changed you have to emit some signals; see the QAbstractItemModel Subclassing documentation.

              M 1 Reply Last reply
              0
              • E Eeli K

                @m.kuncevicius
                Please paste the error message here and tell what code line it refers to.

                QList<Item> ItemModel::item() const
                {
                    return m_item;
                }
                

                returns a copy so you can't change the model's item through that. But even if it would return a reference or a pointer the model wouldn't work properly because it wouldn't send signals when items are changed. Write the modifier API in the model class, hide the item completely inside it. Either write something like ItemModel::setName(int index, QString name) or override setData. In the model's code when the model data is changed you have to emit some signals; see the QAbstractItemModel Subclassing documentation.

                M Offline
                M Offline
                m.kuncevicius
                wrote on last edited by
                #9

                @Eeli-K said in Change data on QAbstractItemModel subclass model:

                ItemModel::setName(int index, QString name)

                I tried this before. But it shows the same error:
                item.cpp:94: error: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
                m_item.at(index).setName(name);
                ^

                void ItemModel::setName(int index, QString name)
                {
                    m_item.at(index).setName(name);
                }
                
                E 1 Reply Last reply
                0
                • M m.kuncevicius

                  @Eeli-K said in Change data on QAbstractItemModel subclass model:

                  ItemModel::setName(int index, QString name)

                  I tried this before. But it shows the same error:
                  item.cpp:94: error: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
                  m_item.at(index).setName(name);
                  ^

                  void ItemModel::setName(int index, QString name)
                  {
                      m_item.at(index).setName(name);
                  }
                  
                  E Offline
                  E Offline
                  Eeli K
                  wrote on last edited by
                  #10

                  @m.kuncevicius Maybe it's because
                  const T &QList::at(int i) const
                  returns a const. Try the [] operator.

                  Then add emit dataChanged to that data modifying method so that the view is automatically updated.

                  M 1 Reply Last reply
                  3
                  • VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #11

                    on top of using operator[],

                    int ItemModel::rowCount(const QModelIndex & parent) const {
                        Q_UNUSED(parent);
                        return m_item.count();
                    }
                    

                    is infinite recursion. for a list it should be:

                    int ItemModel::rowCount(const QModelIndex & parent) const {
                        if(parent.isValid()) return 0;
                        return m_item.count();
                    }
                    

                    void setItem(const QList<Item> &item); why do you replace the entire list every time? You'll be forced to emit modelReset() every time and it's not great.

                    if (index.row() < 0 || index.row() >= m_item.count()) what if the index is invalid? what if the the index has a parent? what happens if I pass an index created by another model?

                    Why don't you just use a QStandardItemModel instead of building your own?

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

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

                    1 Reply Last reply
                    1
                    • E Eeli K

                      @m.kuncevicius Maybe it's because
                      const T &QList::at(int i) const
                      returns a const. Try the [] operator.

                      Then add emit dataChanged to that data modifying method so that the view is automatically updated.

                      M Offline
                      M Offline
                      m.kuncevicius
                      wrote on last edited by
                      #12

                      @Eeli-K Thank you for answers and suggestions!
                      It works right now:

                      void ItemModel::setName(int index, QString name)
                      {
                          m_item[index].setName(name);
                          QModelIndex topLeft = createIndex(index,0);
                          emit dataChanged(topLeft, topLeft);
                      }
                      

                      @VRonin Thanks for comments on my code. Maybe you know some examples how to use QStandardItemModel because reading documentation is pretty exhausting.

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

                        just use the QAbstactItemModel interface. call insertRows(), insertColumns(), setData() and data(). basically you don't have to engineer the ItemModel or the Item at all, no need for subclassing anything, just use it

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

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

                        1 Reply Last reply
                        1

                        • Login

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