1

我有一个代码,它适用于Qt 5.5而不适用于Qt 5.2。问题在于这个枚举

#include <QtCore/QMetaType>
enum Area
{
    Area_A,
    Area_B,
    Area_C
};

Q_DECLARE_METATYPE(Area)

然后我有一个对象,它公开了这个area属性:

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Area area READ area WRITE setArea NOTIFY areaChanged)
public:    
    explicit MyClass(QObject *parent = 0)
        : QObject(parent), m_area(Area_A){}

    Area area() const { return m_area; }    
    void setArea(Area area) {
        m_area = area;
        emit areaChanged(area);
    }

signals:
    void areaChanged(Area area);    
private:
    Area m_area;
};

和 main.cpp:

#include <QtGui/QGuiApplication>
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtQml/QtQml>
#include "MyClass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<MyClass>("GLib", 1, 0, "MyClass");

    MyClass controller;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("controller", &controller);
    engine.load("./main.qml");

    controller.setArea(Area_B);
    return app.exec();
}

它编译,一切正常。但是当我尝试在qml中使用 area 属性时:

import QtQuick 2.0
import QtQuick.Window 2.0
import GLib 1.0

Window {
    visible: true
    id: root

    property int area: controller.area 

    Text {
        id: name
        text: "Test"
        x: area * 30
        y: area * 30
    }
}

如果使用 Qt 5.2(Linux,x64),我有运行时错误:

QMetaProperty::read:无法处理属性“MyClass::area”文件的未注册数据类型“Area”:///home/yech844/devel/test_qml/main.qml:10:24:无法将 [undefined] 分配给 int QMetaProperty::read:无法处理属性“MyClass::area”文件的未注册数据类型“Area”:///home/yech844/devel/test_qml/main.qml:10:24:无法将 [undefined] 分配给 int

这是Qt中的错误吗?为什么我不能使用声明在 Class 范围之外的 Enum?

4

2 回答 2

5

Qt 5.5 引入了 Q_ENUM 宏,它消除了使用 Q_DECLARE_METATYPE 的需要。在此处阅读更多信息:https ://woboq.com/blog/q_enum.html

于 2016-11-18T13:31:58.143 回答
2

我不知道为什么代码在 Qt 5.5 中有效,但我知道为什么它在 Qt 5.2 中无效。

Q_DECLARE_METATYPE(...)仅使该类型在静态(编译)上下文中可用。例如,如果您想使用QVariant::fromValue(...). 在这里,您传递给函数的类型可以在编译时处理,为此,Q_DECLARE_METATYPE就足够了。

但是,如果您想在纯运行时上下文中使用类型,例如在 QML 文档中,Qt 运行时不知道用Q_DECLARE_METATYPE. 为此,需要进行函数调用(在运行时评估),并且qRegisterMetatype是执行此操作的工具:

qRegisterMetaType<Area>("Area");

我对不需要该行的 Qt 5.5 的猜测是,它qmlRegisterType可能会检测到属性中元类型的使用并自动为您调用上述函数。

于 2015-12-03T16:43:20.570 回答