[英]Q_GADGET vs an accessor object for manipulating a polymorphic tree of C++ objects from QML
[英]Passing Q_GADGET as signal parameter from C++ to QML
无法在QML代码中获取C ++对象的属性。 对象作为参数传递给信号。
期望在QML中,可以提取Record
对象的属性text
。 值应为abc
。 QML将对象视为QVariant(Record)
,其属性text
为undefined
。
Record
是一个类似QPoint
的值类型,因此它使用Q_GADGET
声明。
HPP:
#ifndef LISTENP_HPP_
#define LISTENP_HPP_
#include <QObject>
#include "Record.hpp"
class ListenP: public QObject
{
Q_OBJECT
public:
ListenP();
virtual ~ListenP();
void emitGotRecord();
signals:
void gotRecord(Record r);
};
#endif /* LISTENP_HPP_ */
CPP:
#include "ListenP.hpp"
ListenP::ListenP() :
QObject()
{
}
ListenP::~ListenP()
{
}
void ListenP::emitGotRecord()
{
emit gotRecord(Record("abc"));
}
hpp for Record:
#ifndef RECORD_HPP_
#define RECORD_HPP_
#include <QObject>
#include <QMetaType>
class Record
{
Q_GADGET
Q_PROPERTY(QString text READ text WRITE setText)
public:
Record(const QString& text = "");
~Record();
QString text() const
{
return m_text;
}
void setText(const QString& text)
{
m_text = text;
}
private:
QString m_text;
};
Q_DECLARE_METATYPE(Record)
#endif /* RECORD_HPP_ */
记录的cpp:
#include "Record.hpp"
Record::Record(const QString& text) :
m_text(text)
{
}
Record::~Record()
{
}
namespace
{
const int RecordMetaTypeId = qMetaTypeId<Record>();
}
QML篇:
Connections {
target: listenPModel
onGotRecord: {
console.log(r)
console.log(r.text)
}
}
主要部分:
QGuiApplication app(argc, argv);
auto listenP = std::make_shared<ListenP>();
QQuickView view;
view.rootContext()->setContextProperty("listenPModel", &*listenP);
view.setSource(QStringLiteral("src/qml/main.qml"));
view.show();
QtConcurrent::run([=]
{
QThread::sleep(3);
listenP->emitGotRecord();
});
return app.exec();
日志显示:
qml: QVariant(Record)
qml: undefined
Qt 5.5的发行说明说明了新功能:
- Qt核心
- 您现在可以在Q_GADGET中拥有Q_PROPERTY和Q_INVOKABLE ,并且有一种方法可以使用QMetaType系统查询此类小工具的QMetaObject
实际上,使用Qt 5.4编译和运行您的示例会得到与您相同的结果, 而使用Qt 5.5,我得到正确识别的Record
,即得到的结果:
qml: Record(abc)
qml: abc
另外,如Q_DECLARE_METATYPE
文档中所述,传递给宏的类型 - 在本例中为Record
,应提供(1)公共默认构造函数,(2)公共复制构造函数和(3)公共析构函数。 由于Record
是一个非常简单的类,因此不需要提供复制构造函数,因为默认值就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.