Unsolved 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.
-
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