Update QML Listview from slot

I have a problem updating Listview in QML. I looked through many solutions, but I don’t want anything from the "onClicked" event to update all the lists, but how to do it?

source code: http://s000.tinyupload.com/?file_id=86538244635919176055

main.cpp

#include <QApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QDebug> #include "message.h" #include "dataobject.h" int main(int argc, char *argv[]) { QList<QObject*> dataList; dataList.append(new DataObject("1")); dataList.append(new DataObject("2")); dataList.append(new DataObject("3")); QApplication app(argc, argv); QQmlApplicationEngine engine; Message msg; msg.setListInstance(&dataList); auto root_context = engine.rootContext(); root_context->setContextProperty("message",&msg); //root_context->setContextProperty("myModel", QVariant::fromValue(dataList)); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); QQmlContext *ctxt = new QQmlContext(engine.rootContext()); //ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); return app.exec(); } 

message.h

 #ifndef MESSAGE_H #define MESSAGE_H #include <QQmlListProperty> #include <QObject> class Message : public QObject { Q_OBJECT Q_PROPERTY(QQmlListProperty<QObject> myModel READ getList NOTIFY listChanged) public: explicit Message(QObject *parent = 0); ~Message(); void setListInstance(QList<QObject *> *dataList){ list = dataList; } QQmlListProperty<QObject> myModel() const; public slots: void refreshLista(); QQmlListProperty<QObject> getList(); private: QList<QObject *> *list; signals: void listChanged(); }; #endif // MESSAGE_H 

message.cpp

 #include "message.h" #include "dataobject.h" #include <QDebug> Message::Message(QObject *parent):QObject(parent){} Message::~Message(){} void Message::refreshLista(){ list->append(new DataObject("44444")); emit listChanged(); qDebug() << " REFRESH LISTA "; } QQmlListProperty<QObject> Message::getList(){ return QQmlListProperty<QObject>(this, *list); } 

dataobject.h

 #ifndef DATAOBJECT_H #define DATAOBJECT_H #include <QObject> class DataObject : public QObject { Q_OBJECT Q_PROPERTY( QString title READ title WRITE setTitle NOTIFY info) public: DataObject(QObject * parent = 0 ); DataObject(const QString &_title,QObject * parent=0 ); QString title() const; void setTitle(const QString &); signals: void info(); private: QString m_id; QString m_title; }; #endif // DATAOBJECT_H 

dataobject.cpp

 #include "dataobject.h" DataObject::DataObject(QObject * parent): QObject(parent){} DataObject::DataObject(const QString &_title,QObject * parent) :QObject(parent),m_title(_title) {} QString DataObject::title() const { return m_title;} void DataObject::setTitle(const QString &title) { if ( title != m_title ) { m_title = title; emit info();} } 
0
source share
1 answer

Two things:

  • Message should change the model, so Message needs an instance of the model.
  • When the model is changed, it emits a signal in QML, so QML can reload data.

Suppose your Message class is responsible for the model. First pass the model to Message .

 class Message : public QObject { //... private: QList<QObject *> *list; public: void setListInstance(QList<QObject *> *dataList){ list = dataList; } } //main.cpp msg.setListInstance(&dataList); 

Now you can easily change the contents of the model:

 void Message::refreshLista(){ list->append(new DataObject("new")); /*whatever*/} 

However, QML does not reload the model because setContextProperty("myModel", QVariant::fromValue(dataList)); cannot emit signals. Remove this line from main.cpp and create a new property in Message instead:

 class Message : public QObject { Q_OBJECT Q_PROPERTY(QQmlListProperty<QObject> myModel READ getList NOTIFY listChanged) public: QQmlListProperty<QObject> getList(); signals: void listChanged(); } 

In the implementation, create a QQmlListProperty and, if necessary, emits a signal modified by its properties.

 void Message::refreshLista(){ list->append(new DataObject("new")); emit listChanged(); } QQmlListProperty<QObject> Message::getList(){ return QQmlListProperty<QObject>(this, *list); } 

Finally, the ListView in QML should bind to message.myModel instead of myModel :

 ListView { width: 400; height: 300; model: message.myModel //... } 
+1
source

Source: https://habr.com/ru/post/989719/


All Articles