从插槽刷新列表视图QML [英] Refresh QML Listview from Slot

查看:349
本文介绍了从插槽刷新列表视图QML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有在QML清爽列表视图问题,我经历了许多解决方案,看上去但并没有什么具体的,我从事件要onClicked刷新所有列表视图,但如何做到这一点?

源$ C ​​$ C: http://s000.tinyupload.com/?file_id=86538244635919176055

的main.cpp

 的#include<&的QApplication GT;
#包括LT&;&QQmlApplicationEngine GT;
#包括LT&;&QQmlContext GT;
#包括LT&;&QDebug GT;
#包括message.h
#包括dataobject.hINT主(INT ARGC,CHAR *的argv []){
    的QList< QObject的*> DataList控件;
    dataList.append(新数据对象(1));
    dataList.append(新数据对象(2));
    dataList.append(新数据对象(3));
    QApplication的应用程序(ARGC,ARGV);
    QQmlApplicationEngine引擎;
    信息MSG;
    msg.setListInstance(安培; DataList控件);
    汽车root_context = engine.rootContext();
    root_context-> setContextProperty(信息,&安培;味精);
    // root_context-> setContextProperty(基于myModel的QVariant :: fromValue(DataList控件));
    engine.load(QUrl(QStringLiteral(QRC:/main.qml)));
    QQmlContext * ctxt =新QQmlContext(engine.rootContext());
    // ctxt-> setContextProperty(基于myModel的QVariant :: fromValue(DataList控件));
    返回app.exec();
}

message.h

 的#ifndef MESSAGE_H
#定义MESSAGE_H
#包括LT&;&QQmlListProperty GT;
#包括LT&;&QObject的GT;
类信息:公众的QObject {
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<&QObject的GT;基于myModel读的GetList NOTIFY引发ListChanged)
上市:
    显式消息(*的QObject父= 0);
    〜留言();
    无效setListInstance(的QList< QObject的*> * DataList控件){名单= DataList控件; }
    QQmlListProperty<&QObject的GT;基于myModel()const的;
公共插槽:
    无效refreshLista();
    QQmlListProperty<&QObject的GT;的GetList();
私人的:
    的QList< QObject的*> *名单;
信号:
    无效的ListChanged();
};
#ENDIF // MESSAGE_H

message.cpp

 的#includemessage.h
#包括dataobject.h
#包括LT&;&QDebug GT;
消息::留言(* QObject的母公司):QObject的(父){}
消息::〜留言(){}
无效消息:: refreshLista(){
    列表 - >追加(新数据对象(44444));
    发出的ListChanged();
    qDebug()&所述;&下; 刷新LISTA
}
QQmlListProperty<&QObject的GT;消息::的GetList(){
    返回QQmlListProperty<&QObject的GT;(此,*名单);
}

dataobject.h

 的#ifndef DATAOBJECT_H
#定义DATAOBJECT_H
#包括LT&;&QObject的GT;
类数据对象:公众的QObject {Q_OBJECT
    Q_PROPERTY(QString的标题读标题写NOTIFY的setTitle信息)
上市:
    数据对象(QObject的*父= 0);
    数据对象(常量QString的&放大器; _title,QObject的*父= 0);
    标题QString的()const的;
    无效的setTitle(常量QString的&安培;);
信号:
    无效信息();
私人的:
    即QString m_id;
    即QString m_title;
};
#ENDIF // DATAOBJECT_H

dataobject.cpp

 的#includedataobject.h
数据对象::数据对象(QObject的*父):QObject的(父){}
数据对象::数据对象(常量QString的&放大器; _title,QObject的*父)
  :QObject的(父),m_title(_title)
{}
QString的数据对象::标题()const的{返回m_title;}
无效::数据对象的setTitle(常量QString的&安培;标题){
    如果(标题= m_title!){m_title =称号;发出信息();}
}


解决方案

两件事要做:


  1. 消息的修改模型,因此消息所需要的模型的实例。

  2. 在当前模式改变时,发出信号给QML QML这样可以重新加载数据。

假设你的消息类负责模型。首先,模型传递到消息

 类信息:公众的QObject {
    // ...
私人的:
    的QList< QObject的*> *名单;
上市:
    无效setListInstance(的QList< QObject的*> * DataList控件){名单= DataList控件; }
}//main.cpp
msg.setListInstance(安培; DataList控件);

您可以轻松地改变模型的内容现在:

 无效消息:: refreshLista(){列表 - >追加(新数据对象(新)); /*随你*/}

不过,QML会不会重新加载模型,因为 setContextProperty(基于myModel的QVariant :: fromValue(DataList控件)); 无法发出信号。从main.cpp中删除此行并创建消息的新特性而不是:

 类信息:公众的QObject {
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<&QObject的GT;基于myModel读的GetList NOTIFY引发ListChanged)
上市:
    QQmlListProperty<&QObject的GT;的GetList();
信号:
    无效的ListChanged();
}

在实施中,<一href=\"http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html#properties-with-object-list-types\"相对=nofollow称号=剧组的QList到QQmlListProperty>创建QQmlListProperty 并发出属性更改信号时必要的。

 无效消息:: refreshLista(){
    列表 - &GT;追加(新数据对象(新));
    发出的ListChanged();
}
QQmlListProperty&LT;&QObject的GT;消息::的GetList(){
    返回QQmlListProperty&LT;&QObject的GT;(此,*名单);
}

最后,在QML ListView控件应绑定到 message.myModel 而不是基于myModel

 的ListView {
    宽度:400;身高:300;
    型号:message.myModel
    // ...
}

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

解决方案

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

这篇关于从插槽刷新列表视图QML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆