简体   繁体   中英

Enum in Qt property

I have a code, which works with Qt 5.5 and doesn't with Qt 5.2 . Problem is with this enum :

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

Q_DECLARE_METATYPE(Area)

Then I have an object, which exposes this area property:

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

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

It compiles, everything is OK. But when I tried to use area property in qml :

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

I have run-time errors, if Qt 5.2 is used (Linux, x64):

QMetaProperty::read: Unable to handle unregistered datatype 'Area' for property 'MyClass::area' file:///home/yech844/devel/test_qml/main.qml:10:24: Unable to assign [undefined] to int QMetaProperty::read: Unable to handle unregistered datatype 'Area' for property 'MyClass::area' file:///home/yech844/devel/test_qml/main.qml:10:24: Unable to assign [undefined] to int

Is it a bug in Qt? Why I can't use Enum, which is declared out of Class scope?

Qt 5.5 introduced Q_ENUM macro which removed the need to use Q_DECLARE_METATYPE. Read more about it here: https://woboq.com/blog/q_enum.html

I don't know why the code works in Qt 5.5, but I know why it doesn't in Qt 5.2.

Q_DECLARE_METATYPE(...) only makes the type available in static (compiled) context. For example, if you want to use the type in QVariant::fromValue(...) . Here, the type you pass to the function can be processed during compile time, and for this, Q_DECLARE_METATYPE is enough.

However, if you want to use a type in a pure runtime context, for example in a QML document, the Qt runtime doesn't know the type declared with Q_DECLARE_METATYPE . For this, a function call (evaluated during runtime) needs to be made, and qRegisterMetatype is the tool for this:

qRegisterMetaType<Area>("Area");

My guess for Qt 5.5 not needing that line is that qmlRegisterType might detect the use of the meta type in the property and automatically calls the above function for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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