Refresh QML Listview from Slot

a 夏天 提交于 2019-12-25 04:27:32

问题


I have problem with the refreshing Listview in QML I looked through many solutions but there is nothing concrete i want from event "onClicked" refresh all listview but how to do this?

sourcecode: 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();}
}

回答1:


Two things to do:

  1. Message has to modify the model, therefore Message needs the instance of the model.
  2. When model is changed, emits signal to QML so QML can reload data.

Assume that 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);

You can easily change the content of model now:

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

However, QML won't 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 emits property-changed signal when necessary.

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
    //...
}


来源:https://stackoverflow.com/questions/28531983/refresh-qml-listview-from-slot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!