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. QAbstractListModel & QML
Forum Update on Monday, May 27th 2025

QAbstractListModel & QML

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 3 Posters 4.5k 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.
  • Q Offline
    Q Offline
    qdlbp
    wrote on last edited by
    #1

    Hello

    I have some problems to get my qml to work with a QAbstractListModel.

    Here is my code:

    Data.h
    @
    #ifndef DATA_H
    #define DATA_H

    #include <QAbstractListModel>
    #include <QApplication>
    #include <QDebug>
    #include <QHash>
    #include <QList>
    #include <QObject>
    #include <QVariant>
    #include <QVariantMap>

    class Data : public QAbstractListModel
    {
    Q_OBJECT

    protected:
    Data(QObject *parent);

    private:
    enum Role
    {
    Role_Name = Qt::UserRole + 1,
    Role_Age
    };

    public:
    static Data* instance();

    private:
    QHash<int, QByteArray> mRoleNames;
    QList<QVariantMap> mItems;

    public:
    virtual QHash<int, QByteArray> roleNames() const;
    virtual QVariant data(const QModelIndex &index, int role) const;
    virtual int rowCount(const QModelIndex &) const;
    };

    #endif // DATA_H
    @

    Data.cpp
    @
    #include "Data.h"

    Data::Data(QObject *parent)
    : QAbstractListModel(parent)
    {
    mRoleNames[Role_Name] = "name";
    mRoleNames[Role_Age] = "age";

    for (int i = 0; i < 10; ++i)
    {
        QVariantMap item;
    
        item[mRoleNames[Role_Name]] = QString("Name %1").arg(i);
        item[mRoleNames[Role_Age]]  = i;
    
        mItems << item;
    }
    

    }

    Data *Data::instance()
    {
    static Data *p = new Data(qApp);
    return p;
    }

    QHash<int, QByteArray> Data::roleNames() const
    {
    return mRoleNames;
    }

    QVariant Data::data(const QModelIndex &index, int role) const
    {
    Q_ASSERT(index.isValid());

    if ((role >= Role_Name) && (role <= Role_Age))
    {
        return mItems[index.row()][mRoleNames[role]];
    }
    
    return QVariant();
    

    }

    int Data::rowCount(const QModelIndex &) const
    {
    return mItems.count();
    }
    @

    main.cpp
    @
    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QtQml>

    #include "Data.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("data", Data::instance());
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
    return app.exec();
    

    }
    @

    main.qml
    @
    import QtQuick 2.2
    import QtQuick.Controls 1.1

    ApplicationWindow {
    visible: true
    width: 300
    height: 300
    title: qsTr("Hello World")

    ListView {
        anchors.fill: parent
        model: data
        delegate: Text {
            text: name + ", " + age
        }
    }
    

    }
    @

    When i run the application i get this message:
    @
    QQmlExpression: Expression qrc:///main.qml:68:16 depends on non-NOTIFYable properties: QQuickListView::data
    @

    Also i see that no one methods of the Data class, except instance(), are called.

    What is wrong with my code?

    1 Reply Last reply
    0
    • H Offline
      H Offline
      hpollak
      wrote on last edited by
      #2

      You hava to implement the notification if the data changed.

      There is a good tutorial about C++ models to QML "see: ":http://lemirep.wordpress.com/2013/04/06/a-practical-case-exposing-qt-c-models-to-qml/

      1 Reply Last reply
      0
      • Q Offline
        Q Offline
        qdlbp
        wrote on last edited by
        #3

        Thanks for your reply.

        But in the "documentation":http://qt-project.org/doc/qt-5/qtquick-modelviewsdata-cppmodels.html#qabstractitemmodel i found next:
        @A QAbstractItemModel can also automatically notify a QML view when the model data changes.@

        1 Reply Last reply
        0
        • Q Offline
          Q Offline
          qdlbp
          wrote on last edited by
          #4

          I modified my Data.cpp:
          @
          #include "Data.h"

          Data::Data(QObject *parent)
          : QAbstractListModel(parent)
          {
          qDebug() << "Data::Data()";
          mRoleNames[Role_Name] = "name";
          mRoleNames[Role_Age] = "age";

          const int n = 10;
          
          beginInsertRows(QModelIndex(), 0, n);
          
          for (int i = 0; i < n; ++i)
          {
              QVariantMap item;
          
              item[mRoleNames[Role_Name]] = QString("Name %1").arg(i);
              item[mRoleNames[Role_Age]]  = i;
          
              mItems << item;
          }
          qDebug() << mItems.count();
          
          endInsertRows();
          

          }

          Data *Data::instance()
          {
          qDebug() << "Data::instance()";
          static Data *p = new Data(qApp);
          return p;
          }

          QHash<int, QByteArray> Data::roleNames() const
          {
          qDebug() << "Data::roleNames()";
          return mRoleNames;
          }

          QVariant Data::data(const QModelIndex &index, int role) const
          {
          qDebug() << "Data::data()";
          Q_ASSERT(index.isValid());

          if ((role >= Role_Name) && (role <= Role_Age))
          {
              return mItems[index.row()][mRoleNames[role]];
          }
          
          return QVariant();
          

          }

          int Data::rowCount(const QModelIndex &) const
          {
          qDebug() << "Data::rowCount()" << mItems.count();
          return mItems.count();
          }
          @

          So now i get this output:
          @
          Data::instance()
          Data::Data()
          Data::rowCount() 0
          10
          QQmlExpression: Expression qrc:///main.qml:76:16 depends on non-NOTIFYable properties: QQuickListView::data
          @

          Strange...

          1 Reply Last reply
          0
          • F Offline
            F Offline
            fxam
            wrote on last edited by
            #5

            Change the model name in QML's ListView to something other than data, seems like it is referring to Item's "data":http://qt-project.org/doc/qt-5/qml-qtquick-item.html#data-prop property. I renamed my working model to data and had the same error.

            1 Reply Last reply
            0
            • Q Offline
              Q Offline
              qdlbp
              wrote on last edited by
              #6

              Oh, right. Thanks

              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