QAbstractListModel & QML
-
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_OBJECTprotected:
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.1ApplicationWindow {
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?
-
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/
-
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...
-
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.