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. QAbstractListModel need help with data() and setData()

QAbstractListModel need help with data() and setData()

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 4.8k 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.
  • S Offline
    S Offline
    Slash200
    wrote on last edited by koahnig
    #1

    Hello,

    I have a QAbstractListModel with own roles for my values that should be editable:
    this is the model:

    #include <QAbstractListModel>
    #include <QStringList>
    #include "datasourceobject.h"
    
    
    class datasourcemodel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum datasourceRoles {
            idRole = Qt::UserRole + 1,
            nameRole,
            displaynameRole,
            valueRole
        };
    
        datasourcemodel(QObject *parent = nullptr);
    
        void addDataSourceObject(const DataSourceObject &DataSourceObject);
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const;
    
    
    
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    
        bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
    
        //Qt::ItemFlags flags(const QModelIndex &index) const;
    
    protected:
        QHash<int, QByteArray> roleNames() const;
    
    private:
        QList<DataSourceObject> m_DataSourceObjects;
    
    };
    
    #include "datasourcemodel.h"
    
    datasourcemodel::datasourcemodel(QObject *parent)
        : QAbstractListModel (parent)
    {
    }
    
    void datasourcemodel::addDataSourceObject(const DataSourceObject &DataSourceObject){
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_DataSourceObjects << DataSourceObject;
        endInsertRows();
    }
    
    int datasourcemodel::rowCount(const QModelIndex & parent) const{
        Q_UNUSED(parent);
        return m_DataSourceObjects.count();
    }
    
    QVariant datasourcemodel::data(const QModelIndex & index, int role) const{
        if(index.row() < 0 || index.row() >= m_DataSourceObjects.count())
            return  QVariant();
    
        const DataSourceObject &dataSourceObject = m_DataSourceObjects[index.row()];
        if (role == idRole)
            return dataSourceObject.id();
        else if (role == nameRole)
            return dataSourceObject.name();
        else if (role == displaynameRole)
            return dataSourceObject.displayname();
        else if (role == valueRole)
            return dataSourceObject.value();
        return QVariant();
    }
    
    bool ::datasourcemodel::setData(const QModelIndex &index, const QVariant &value, int role){
    
        DataSourceObject &dataSourceObject = m_DataSourceObjects[index.row()];
        if(role == idRole){
            dataSourceObject.setid(value.toInt());
            return true;
        }
        else if(role == nameRole){
            dataSourceObject.setname(value.toString());
            return true;
        }
        else if(role == displaynameRole){
            dataSourceObject.setdisplayname(value.toString());
            return true;
        }
        else if(role == valueRole){
            dataSourceObject.setvalue(value.toDouble());
            return true;
        }
        return false;
    
    }
    
    
    QHash<int, QByteArray> datasourcemodel::roleNames() const {
        QHash<int, QByteArray> roles;
        roles[idRole] = "id";
        roles[nameRole] = "name";
        roles[displaynameRole] = "displayname";
        roles[valueRole] = "value";
        return roles;
    }
    

    This is the object thats stored in the model:

    #include "datasourceobject.h"
    
    DataSourceObject::DataSourceObject(const int &id, const QString &name, const QString &displayname, const double &value)
        : m_id(id), m_name(name), m_displayname(displayname), m_value(value)
    {
    
    }
    
    
    int DataSourceObject::id() const
    {
        return m_id;
    }
    
    void DataSourceObject::setid(const int &id)
    {
        if (id != m_id) {
            m_id = id;
            //emit idChanged();
        }
    }
    
    
    QString DataSourceObject::name() const
    {
        return m_name;
    }
    
    void DataSourceObject::setname(const QString &name)
    {
        if (name != m_name) {
            m_name = name;
            //emit nameChanged();
        }
    }
    
    
    QString DataSourceObject::displayname() const
    {
        return m_displayname;
    }
    
    void DataSourceObject::setdisplayname(const QString &displayname)
    {
        if (displayname != m_displayname) {
            m_displayname = displayname;
            //emit displaynameChanged();
        }
    }
    
    
    double DataSourceObject::value() const
    {
        return m_value;
    }
    
    void DataSourceObject::setvalue(const double &value)
    {
        //if(value != m_value) {
            m_value = value;
            //emit valueChanged();
        //}
    }
    

    I can't get datasourcemodel::data and datasourcemodel::setData to work.
    I can't figure out how to tell which role should be edited.

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Slash200 said in QAbstractListModel need help with data() and setData():

      I can't figure out how to tell which role should be edited.

      Can you explain this? For editing normally Qt::EditRole is used.

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

      S 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        @Slash200 said in QAbstractListModel need help with data() and setData():

        I can't figure out how to tell which role should be edited.

        Can you explain this? For editing normally Qt::EditRole is used.

        S Offline
        S Offline
        Slash200
        wrote on last edited by Slash200
        #3

        @Christian-Ehrlicher

        I probably have a little problem understanding how the role concept works.
        I tried to show a object in with: qWarning() << m_DataSourceModel.data(childIndex, Qt::DisplayRole); where Childindex is my desired object

        But it return QVariant(Invalid)

        Also I tried editing with m_DataSourceModel.setData(childIndex,QVariant(value), Qt::EditRole); but it does not work

        But I don't understand how I edit a value in my Child and how to use

        QHash<int, QByteArray> datasourcemodel::roleNames() const {
            QHash<int, QByteArray> roles;
            roles[idRole] = "id";
            roles[nameRole] = "name";
            roles[displaynameRole] = "displayname";
            roles[valueRole] = "value";
            return roles;
        }
        

        I read this documentation but it's very hard to understand for me

        1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by
          #4

          Are you using the model with Qt or QML ?
          You have defined the roles starting from Qt::userRole + 1. Inside the data function you are returning the data based on this numbers. When you pass Qt::DisplayRole, it is asking for value passing the value as 0(zero). Inside your data(..) function nothing matches for 0. So it returns invalid QVariant.

          Just quickly check this, try like following and see how it works.
          enum datasourceRoles {
          idRole=0,
          nameRole,
          displaynameRole,
          valueRole
          };

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          S 1 Reply Last reply
          1
          • dheerendraD dheerendra

            Are you using the model with Qt or QML ?
            You have defined the roles starting from Qt::userRole + 1. Inside the data function you are returning the data based on this numbers. When you pass Qt::DisplayRole, it is asking for value passing the value as 0(zero). Inside your data(..) function nothing matches for 0. So it returns invalid QVariant.

            Just quickly check this, try like following and see how it works.
            enum datasourceRoles {
            idRole=0,
            nameRole,
            displaynameRole,
            valueRole
            };

            S Offline
            S Offline
            Slash200
            wrote on last edited by
            #5

            @dheerendra
            Hi!
            I'm using it as datamodel for QML.

            I removed the "+ 1" in my programm and it's still returning invalid.

            When I change idRole to 0 , the program crashed with a index out of range error

            1 Reply Last reply
            0
            • dheerendraD Offline
              dheerendraD Offline
              dheerendra
              Qt Champions 2022
              wrote on last edited by
              #6

              If you are using for QML, not sure why you are calling the data function directly. Since it is crashing you must be passing some null index to fetch the value. To make your like simple, I have given small example. Try this. See how model works. Based on this modify your program.

              class MyModel : public QAbstractListModel
              {
              public:
              enum datasourceRoles {
              idRole = Qt::UserRole + 1,
              nameRole,
              displaynameRole,
              valueRole
              };
              MyModel();
              QVariant data(const QModelIndex &index, int role) const;
              int rowCount(const QModelIndex &parent) const;
              QModelIndex getIndex(int r, int c, void *p);
              private :
              int a[100];
              };

              QVariant MyModel::data(const QModelIndex &index, int role) const
              {
              int v = a[index.row()];
              QVariant val;
              switch(role){

              case idRole:
                   val = v;break;
              case nameRole:
                   val = v+10;break;
              case displaynameRole:
                  val = v+20;break;
              case valueRole :
                  val = v+30;break;
              }
              
              return val;
              

              }

              int MyModel::rowCount(const QModelIndex &parent) const
              {
              return 10;
              }

              QModelIndex MyModel::getIndex(int r, int c, void *p)
              {
              return this->createIndex(r,c,p);
              }

              =====main.cpp====
              MyModel *model1 = new MyModel;
              QModelIndex id1 = model1->getIndex(1,0,0);
              QVariant v1 = model1->data(id1,Qt::UserRole+1);
              QVariant v2 = model1->data(id1,Qt::UserRole+2)
              qDebug() << "-----> " << v1.toInt() <<v2.toInt() << endl;

              Dheerendra
              @Community Service
              Certified Qt Specialist
              http://www.pthinks.com

              S 1 Reply Last reply
              0
              • dheerendraD dheerendra

                If you are using for QML, not sure why you are calling the data function directly. Since it is crashing you must be passing some null index to fetch the value. To make your like simple, I have given small example. Try this. See how model works. Based on this modify your program.

                class MyModel : public QAbstractListModel
                {
                public:
                enum datasourceRoles {
                idRole = Qt::UserRole + 1,
                nameRole,
                displaynameRole,
                valueRole
                };
                MyModel();
                QVariant data(const QModelIndex &index, int role) const;
                int rowCount(const QModelIndex &parent) const;
                QModelIndex getIndex(int r, int c, void *p);
                private :
                int a[100];
                };

                QVariant MyModel::data(const QModelIndex &index, int role) const
                {
                int v = a[index.row()];
                QVariant val;
                switch(role){

                case idRole:
                     val = v;break;
                case nameRole:
                     val = v+10;break;
                case displaynameRole:
                    val = v+20;break;
                case valueRole :
                    val = v+30;break;
                }
                
                return val;
                

                }

                int MyModel::rowCount(const QModelIndex &parent) const
                {
                return 10;
                }

                QModelIndex MyModel::getIndex(int r, int c, void *p)
                {
                return this->createIndex(r,c,p);
                }

                =====main.cpp====
                MyModel *model1 = new MyModel;
                QModelIndex id1 = model1->getIndex(1,0,0);
                QVariant v1 = model1->data(id1,Qt::UserRole+1);
                QVariant v2 = model1->data(id1,Qt::UserRole+2)
                qDebug() << "-----> " << v1.toInt() <<v2.toInt() << endl;

                S Offline
                S Offline
                Slash200
                wrote on last edited by
                #7

                @dheerendra
                I have to modify the data in Qt and display it with QML. thats why I need display and editing in Qt.
                Qt is getting data via network and has to store it in this model(changes the values-variable of the objects-no other variable of the objects)

                With your solution the data isn't displayed corectly in QML and debugging shows values but not the correct ones.

                1 Reply Last reply
                0
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on last edited by
                  #8

                  Can you show your sample in qml ?

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  S 1 Reply Last reply
                  0
                  • dheerendraD dheerendra

                    Can you show your sample in qml ?

                    S Offline
                    S Offline
                    Slash200
                    wrote on last edited by Slash200
                    #9

                    It is now working.
                    I can see the data beeing updatet in den debug output. But the data isn't updated in QML

                    E 1 Reply Last reply
                    0
                    • S Slash200

                      It is now working.
                      I can see the data beeing updatet in den debug output. But the data isn't updated in QML

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

                      @Slash200 "The dataChanged() signal should be emitted if the data was successfully set." (See QAbstractItemModel::setData)

                      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