QML ListView in qml is not updated when model changed
-
I am trying to update a model in a QML ListView from a cpp file..
this is my model implementation albummodel.h
#include <QAbstractListModel> #include <QStringList> #include <QQmlListProperty> class Album { public: Album(const QString &type, const QString &size); QString type() const; QString size() const; private: QString m_type; QString m_size; }; class AlbumModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QQmlListProperty<QObject> myModel NOTIFY listChanged) public: enum AlbumRoles { TypeRole = Qt::UserRole + 1, SizeRole }; AlbumModel(QObject *parent = 0); //QQmlListProperty<QObject> getList(); void addAlbum(const Album &album); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<Album> m_albums; signals: void listChanged(); #include <QAbstractListModel> #include <QStringList> #include <QQmlListProperty> class Album { public: Album(const QString &type, const QString &size); QString type() const; QString size() const; private: QString m_type; QString m_size; }; class AlbumModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QQmlListProperty<QObject> myModel NOTIFY listChanged) public: enum AlbumRoles { TypeRole = Qt::UserRole + 1, SizeRole }; AlbumModel(QObject *parent = 0); //QQmlListProperty<QObject> getList(); void addAlbum(const Album &album); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<Album> m_albums; signals: void listChanged(); };
This is my albummodel.cpp
#include "albummodel_mediaplayer.h" Album::Album(const QString &type, const QString &size) : m_type(type), m_size(size) { } QString Album::type() const { return m_type; } QString Album::size() const { return m_size; } AlbumModel::AlbumModel(QObject *parent) : QAbstractListModel(parent) { } void AlbumModel::addAlbum(const Album &album) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_albums << album; endInsertRows(); emit listChanged(); } int AlbumModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent); return m_albums.count(); } QVariant AlbumModel::data(const QModelIndex & index, int role) const { if (index.row() < 0 || index.row() >= m_albums.count()) return QVariant(); const Album &Album = m_albums[index.row()]; if (role == TypeRole) return Album.type(); else if (role == SizeRole) return Album.size(); return QVariant(); } QHash<int, QByteArray> AlbumModel::roleNames() const { QHash<int, QByteArray> roles; roles[TypeRole] = "type"; roles[SizeRole] = "size"; return roles; } /*QQmlListProperty<QObject> AlbumModel::getList(){ return QQmlListProperty<QObject>(this, *list); }*/
and my qml file
ListView { model: myModel .... }
But the model isn't updated.....Can someone help me to get the connection right?
-
@lomilomi said in QML ListView in qml is not updated when model changed:
Q_PROPERTY(QQmlListProperty<QObject> myModel NOTIFY listChanged)
This is wrong, you don't need any
Q_PROPERTY
when using aQAbstract*Model
.In QML, you should simply point
model
to an instance ofAlbumModel
. I don't know how you create/ pass it from C++ to QML so I can't exactly tell you how to do it in your case.In general, though, setting it through root context property of the QQmlEngine is the easiest route and works well.
-
@lomilomi said in QML ListView in qml is not updated when model changed:
Q_PROPERTY(QQmlListProperty<QObject> myModel NOTIFY listChanged)
This is wrong, you don't need any
Q_PROPERTY
when using aQAbstract*Model
.In QML, you should simply point
model
to an instance ofAlbumModel
. I don't know how you create/ pass it from C++ to QML so I can't exactly tell you how to do it in your case.In general, though, setting it through root context property of the QQmlEngine is the easiest route and works well.
This is my main program
void main() { qmlRegisterType<AlbumModel>("AlbumModel",1,0,"AlbumModel"); Album g("test", "test"); AlbumModel h(); h.addAlbum(g); }
Qml file
import AlbumModel 1.0 ListView { model: AlbumModel.myModel delegate: playListThumbnail Component { id: playListThumbnail Item { Text { id: albumTitleText text: type//item_title }} .... }
-
You create 2 different instances of AlbumModel: one in C++ and one in QML. Then you add an album in C++ - but obviously the other object in QML won't know about it.
Solution: do not create 2 objects. For example, in C++:
void main() { Album g("test", "test"); AlbumModel h(); h.addAlbum(g); engine.rootContext()->setContextProperty("AlbumModel", &h); }
With this it should work fine.
-
This is almost verbatim the same as this example on the wiki