Обновить список QML из слота

У меня проблема с обновлением списка в QML. Я просмотрел множество решений, но нет ничего конкретного, что я хочу от события «onClicked», чтобы обновить весь список, но как это сделать?

исходный код: 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();
}

сообщение.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

сообщение.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);
}       

объект данных.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

объект данных.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();}
}

person Sławomir Kudła    schedule 15.02.2015    source источник
comment
Это слишком много кода для вопроса о переполнении стека. Пожалуйста, отредактируйте его, указав только необходимые части с минимальным, полным и проверяемым примером.   -  person MrEricSir    schedule 16.02.2015
comment
я старался быть кратким, пожалуйста, посмотрите   -  person Sławomir Kudła    schedule 16.02.2015


Ответы (1)


Две вещи, которые нужно сделать:

  1. Message должен изменить модель, поэтому Message нужен экземпляр модели.
  2. При изменении модели посылает сигнал в QML, чтобы QML мог перезагрузить данные.

Предположим, что ваш класс Message отвечает за модель. Сначала передайте модель Message.

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

//main.cpp
msg.setListInstance(&dataList);

Теперь вы можете легко изменить содержимое модели:

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

Однако QML не перезагрузит модель, поскольку setContextProperty("myModel", QVariant::fromValue(dataList)); не может генерировать сигналы. Удалите эту строку из main.cpp и вместо этого создайте новое свойство в Message:

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

В реализации создает QQmlListProperty и при необходимости выдает сигнал об изменении свойства.

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

Наконец, ListView в QML должен быть привязан к message.myModel вместо myModel:

ListView {
    width: 400; height: 300;
    model: message.myModel
    //...
}
person mcchu    schedule 16.02.2015