在 QML QList <QPair>中接收带有参数的 c++ 信号



我试图弄清楚如何从QML中的C++信号中获取QList>,我只得到QVariant(RecordList,(或QVariant(QList,(。尝试使用不同的支持序列类型,它们工作正常(QList。如果有人能帮助我理解我的错误,我将不胜感激。亲切问候。

jsonreaderasync.h

typedef QPair<qreal,qreal>Record;
typedef QList<Record>RecordList;
class JsonReaderAsync : public QObject
{
Q_OBJECT
public:
explicit JsonReaderAsync(QObject *parent = nullptr);
Q_INVOKABLE void start(const QString& fileName);
signals:
void started();
//void finished(QList<qreal> record);
void finished(RecordList record);
//void finished(QList<Record> record); 
};

jsonreaderasync.cpp

#include <QDebug>
#include "jsonreaderasync.h"
Q_DECLARE_METATYPE(Record)
Q_DECLARE_METATYPE(RecordList)
//Q_DECLARE_METATYPE(QList<Record>)

JsonReaderAsync::JsonReaderAsync(QObject *parent) : QObject(parent)
{
qRegisterMetaType<Record>("Record");
qRegisterMetaType<RecordList>("RecordList"); // qml prints QVariant(RecordList, )
//qRegisterMetaType<QList<Record>>("QList<Record>"); //qml prints QVariant(QList<Record>, )
}
void JsonReaderAsync::start(const QString &fileName)
{
QList<Record> record;
record.append(qMakePair(1,1));
record.append(qMakePair(1,2));
record.append(qMakePair(1,3));
//    QList<qreal> foo;
//    foo.append(1);
//    foo.append(1);
//    foo.append(1);
emit finished(record);
}

主.cpp

#include "jsonreaderasync.h"
typedef QPair<qreal,qreal>Record;
typedef QList<QPair<qreal,qreal>>RecordList;

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine *engine = new QQmlApplicationEngine;
JsonReaderAsync* dataReaderAsync = new JsonReaderAsync();
engine->rootContext()->setContextProperty("JsonReaderAsync", dataReaderAsync);
engine->load(QUrl(QStringLiteral("main.qml")));
return app.exec();
}

主.qml

import QtQuick 2.12
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.13
import QtQuick.Window 2.13
import QtQuick.Controls 2.12
import QtCharts 2.3
Window {
id: appWindow
visible: true
minimumWidth : 400
minimumHeight: 400
Connections
{
target: JsonReaderAsync
onStarted:{
console.log("onStarted")
}
onFinished:{
console.log("onFinished")
console.log(record)
console.log(record[0])
}
}
Button {
width : 40
height: 40
anchors.centerIn: parent
onClicked: {
JsonReaderAsync.start("")
}
}
}

在 QML 中,元类型系统是 QML 引擎从 QML 环境访问C++结构的唯一方法。

也就是说,只有预定义C++类型和具有Q_PROPERTY声明的自定义对象才能从 QML 环境访问。

这是我推荐的(最简单的(修改:

jsonreaderasync.h

#include <QObject>
#include <QVariant>
class Record : public QPair<qreal, qreal> {
Q_GADGET
Q_PROPERTY(qreal first  MEMBER first  CONSTANT FINAL)
Q_PROPERTY(qreal second MEMBER second CONSTANT FINAL)
public:
Record() = default;
Record(qreal a, qreal b) : QPair<qreal, qreal>(a, b) {}
};
class JsonReaderAsync : public QObject
{
Q_OBJECT
public:
explicit JsonReaderAsync(QObject *parent = nullptr);
Q_INVOKABLE void start(const QString& fileName);
signals:
void started();
void finished(QVariantList record);  // RecordList
};

jsonreaderasync.cpp

#include <QDebug>
#include "jsonreaderasync.h"
JsonReaderAsync::JsonReaderAsync(QObject *parent) : QObject(parent)
{
qRegisterMetaType<Record>("Record");
}
void JsonReaderAsync::start(const QString &fileName)
{
QVariantList record;
record.append(QVariant::fromValue(Record(1,1)));
record.append(QVariant::fromValue(Record(1,2)));
record.append(QVariant::fromValue(Record(1,3)));
emit finished(record);
}

现在,您可以从 QML 访问记录:

onFinished: {
for (var i = 0; i < record.length; ++i)
console.log(record[i].first + "->" + record[i].second);
}

请注意,在 C++ 对象和 QML 对象之间进行转换确实会产生一些开销,如果这些代码对性能敏感,请考虑使用 C++ 数据模型。

虽然@GPBeta解决方案有效,但我希望 Qml 支持的对具有更大的灵活性。我尝试使用模板,但Q_GADGET不支持它。可能有一个智能包装器(模板 + QVariant(解决方案,我想......尽管如此,这是我解决问题的方法:

class PairQml {
Q_GADGET
Q_PROPERTY(QVariant first MEMBER first CONSTANT FINAL)
Q_PROPERTY(QVariant second MEMBER second CONSTANT FINAL)
public:
PairQml() = default;
PairQml(QVariant f, QVariant s): first(f), second(s) {}
QVariant first;
QVariant second;
};

不要忘记注册:qRegisterMetaType<PairQml>("PairQml");

相关内容

  • 没有找到相关文章

最新更新