【发布时间】:2017-04-22 13:16:54
【问题描述】:
我在文件 mygadget.h 中定义了一个 Q_GADGET MyGadget
#include <QObject>
class MyGadget {
Q_GADGET
Q_PROPERTY(int value READ value CONSTANT)
public:
MyGadget() = default;
MyGadget(int i)
: _value{i}
{
}
int value() const
{
return _value;
}
private:
int _value{0};
};
Q_DECLARE_METATYPE(MyGadget)
Q_DECLARE_METATYPE(MyGadget*)
还有一个 Context 类,它拥有一个 MyGadget 的实例并通过 Q_PROPERTY 向 QML 公开指向它的指针:
#include <QObject>
#include "mygadget.h"
class Context : public QObject
{
Q_OBJECT
Q_PROPERTY(MyGadget* gadget READ gadget CONSTANT)
public:
explicit Context()
: QObject{nullptr}
{
}
MyGadget* gadget() {
return &_gadget;
}
private:
MyGadget _gadget{4};
};
Context 的实例在 main 中创建,并作为上下文属性暴露给 QML:
#include <QGuiApplication>
#include <QQuickView>
#include <QString>
#include <QQmlContext>
#include "context.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
Context c;
// register MyGadget
qmlRegisterUncreatableType<MyGadget>("Test", 1, 0, "MyGadget", "");
qRegisterMetaType<MyGadget*>(); // <- removing this doesn't change anything
// make Context instance a context propery
view.rootContext()->setContextProperty("context", &c);
// show QML
view.setSource(QUrl{QStringLiteral("qrc:/main.qml")});
view.show();
return app.exec();
}
与此一起使用的 QML 文件是
import QtQuick 2.5
import Test 1.0
Rectangle {
height: 600
width: 800
visible: true
Text {
text: qsTr("Hello World " + context.gadget.value)
anchors.centerIn: parent
}
}
一切编译正常,但运行时没有显示任何文本,QML 发出警告
qrc:/main.qml:9: TypeError: Cannot read property 'value' of null.
如果我删除了对main 中qmlRegisterUncreatableType<MyGadget> 的调用以及QML 文件中对应的import Test 1.0,则会显示文本“Hello World undefined”。
我让它按预期打印“Hello World 4”的唯一方法是让Context::gadget返回存储的MyGadget对象的副本而不是指向它的指针,或者使MyGadget成为@987654337 @ 反而。但是这两个在我的实际应用程序中都不是可行的选项,因为我在这里需要引用语义,但在其他地方我也希望在这个例子中为与 MyGadget 对应的类有值语义。
如何让 QML 读取正确的属性值?
【问题讨论】:
标签: c++ qt qml qproperty qgadget