Перечисление в свойстве Qt

У меня есть код, который работает с Qt 5.5 и не работает с Qt 5.2. Проблема с этим перечислением:

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

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

Компилируется, все ок. Но когда я попытался использовать свойство area в 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
    }
}

У меня есть ошибки времени выполнения, если используется Qt 5.2 (Linux, x64):

QMetaProperty:: read: Невозможно обработать незарегистрированный тип данных 'Area' для свойства 'MyClass::area' file:///home/yech844/devel/test_qml/main.qml:10:24: Невозможно назначить [undefined] для int QMetaProperty::read: Невозможно обработать незарегистрированный тип данных 'Area' для свойства 'MyClass::area' file:///home/yech844/devel/test_qml/main.qml:10:24: Невозможно назначить [undefined] для int

Это ошибка в Qt? Почему я не могу использовать Enum, который объявлен вне области видимости?

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 может обнаружить использование мета-типа в свойстве и автоматически вызовет вышеуказанную функцию для вас.

Qt 5.5 представил макрос Q_ENUM, который убрал необходимость использовать Q_DECLARE_METATYPE. Подробнее об этом читайте здесь: https://woboq.com/blog/q_enum.html

Другие вопросы по тегам