QML:使用自定义QObject键入Error

时间:2014-09-05 21:04:38

标签: c++ qt qml

我尝试用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();
}

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

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

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

qml.qrc:

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>

现在,我希望QML生成的值可以直接输入C ++中的对象(即MouseArea中的onReleased处理程序试图写入myData字段)。然而,这个基本的概念证明并不起作用,但我并不理解为什么。

我得到的错误(拖动和释放鼠标按钮时)是: qrc:///main.qml:29:TypeError:输入错误

哪一行符合&#34; myData.a = mouse.x;&#34;,所以它会立即失败。

我想知道哪里出错了?我尝试过使用int,double,QVariant和qreal等字段,但没有一个有效。在QML中基本无法链接这样的对象吗?如果是这样,任何想法,例如,如何在Qt源代码中实现anchors.fill?

1 个答案:

答案 0 :(得分:7)

如果您分解错误来自的行上的表达式,这会有所帮助。首先尝试打印myData.a

print(myData.a)
myData.a = mouse.x;
myData.b = mouse.y;
  

qrc:///main.qml:31:TypeError:无法读取属性&#39; a&#39;为null

所以,myDatanull。我们可以使用其他基于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;
    }
}
  

qml:null

因此,您可以通过初始化属性来修复此错误:

property DataObject myData: DataObject {}

您可以将基于QObject的属性视为JavaScript的指针;它们可以是null或指向有效对象......或者是undefined。 :)我无法找到有关此here的任何内容,但应该提及此行为。

如果您想简化某些事情,可以让对象默认为您构建,方法是将其设为MouseArea的子对象,而不是属性:

MouseArea {
    DataObject {
        id: myData
    }
    anchors.fill: parent
    drag.target: parent

    onReleased: {
        myData.a = mouse.x;
        myData.b = mouse.y;
    }
}

目前,您无法从C ++引用此属性。但是,您可以通过两种方式实现此目的:

  1. 声明项目的property alias
  2. 给它objectName并使用QObject::findChild查找。