繁体   English   中英

QML:使用自定义QObject键入Error

[英]QML: Type Error with custom QObject

我正在尝试使用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:类型错误

这与“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;

qrc:///main.qml:31:TypeError:无法读取null的属性“a”

所以, 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 :)我在这里找不到任何关于此的内容,但这就是应该提到这种行为的地方。

如果你想简化一些事情,你可以通过使它成为MouseArea的子对象而不是属性来为你构造默认构造的对象:

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

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

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

  1. 声明项目的属性别名
  2. 给它一个objectName并使用QObject :: findChild来查找它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM