我正在尝试使用QML来尝试使其更容易合并两者更加无缝; 确切地说,我正在尝试将具有结构化数据的对象链接到QML.
我有以下设置:
main.cpp中:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "dataobject.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qmlRegisterType<DataObject>("DO", 1,0,"DataObject");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)
dataobject.h:
#ifndef DATAOBJECT_H
#define DATAOBJECT_H
#include <QObject>
#include <QVariant>
#include <iostream>
class DataObject : public QObject
{
Q_OBJECT
Q_PROPERTY(qreal a MEMBER a NOTIFY aChanged)
Q_PROPERTY(qreal b MEMBER b NOTIFY bChanged)
public:
explicit DataObject(QObject *parent = 0);
signals:
void aChanged();
void bChanged();
public slots:
void printState() {
using namespace std;
cout << a << ", " << b << endl;
}
private:
qreal a;
qreal b;
};
#endif // DATAOBJECT_H
Run Code Online (Sandbox Code Playgroud)
dataobject.cpp:
#include "dataobject.h"
DataObject::DataObject(QObject *parent) :
QObject(parent)
{
connect(this, SIGNAL(aChanged()), this, SLOT(printState()));
connect(this, SIGNAL(bChanged()), this, SLOT(printState()));
}
Run Code Online (Sandbox Code Playgroud)
main.qml:
import DO 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
Text {
text: qsTr("Hello World")
MouseArea {
property DataObject myData;
anchors.fill: parent
drag.target: parent
onReleased: {
myData.a = mouse.x;
myData.b = mouse.y;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
qml.qrc:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
Run Code Online (Sandbox Code Playgroud)
现在,我希望QML生成的值可以直接输入C++中的对象(即MouseArea中的onReleased处理程序试图写入myData字段).但是,这个基本的概念证明不起作用,但我真的不明白为什么.
我得到的错误(拖动和释放鼠标按钮)是:qrc:///main.qml:29:TypeError:类型错误
这与"myData.a = mouse.x;"行匹配,因此它会立即失败.
我知道哪里出错了?我尝试过使用int,double,QVariant和qreal等字段,其中没有一个有效.在QML中基本无法链接这样的对象吗?如果是这样,任何想法,例如,如何在Qt源代码中实现anchors.fill?
如果您分解错误来自的行上的表达式,它会有所帮助.myData.a首先尝试打印:
print(myData.a)
myData.a = mouse.x;
myData.b = mouse.y;
Run Code Online (Sandbox Code Playgroud)
qrc:///main.qml:31:TypeError:无法读取null的属性"a"
所以,myData是的null.我们可以用另一种QObject类型来验证这个:
MouseArea {
property DataObject myData;
property Item item
anchors.fill: parent
drag.target: parent
onReleased: {
print(item)
myData.a = mouse.x;
myData.b = mouse.y;
}
}
Run Code Online (Sandbox Code Playgroud)
qml:null
因此,您可以通过初始化属性来修复此错误:
property DataObject myData: DataObject {}
Run Code Online (Sandbox Code Playgroud)
您可以将基于QObject的属性视为JavaScript的指针; 他们可以是null或指向一个有效的对象......或者是undefined.:)我在这里找不到任何关于此的内容,但这就是应该提到这种行为的地方.
如果你想简化一些事情,你可以通过使它成为一个子对象MouseArea而不是一个属性来为你构造默认构造的对象:
MouseArea {
DataObject {
id: myData
}
anchors.fill: parent
drag.target: parent
onReleased: {
myData.a = mouse.x;
myData.b = mouse.y;
}
}
Run Code Online (Sandbox Code Playgroud)
目前,您将无法从C++引用此属性.但是,您可以通过两种方式实现此目的:
objectName并使用QObject :: findChild来查找它.