Solved Cannot compare C++ enum in QML
-
Hi,
I have exported a C++ enum to QML and it seems to be recognized correctly in QML. When I use the enum as a property type in another class then the property isn't compared correctly with the enum value and comparison returns false. I have added a small example below.
Class with enum
#ifndef TYPES_H #define TYPES_H #include <QObject> class SystemStateClass { Q_GADGET public: enum SystemStateEnum { Idle = 0, MainView, }; Q_ENUM(SystemStateEnum) private: explicit SystemStateClass() {} }; using SystemState = SystemStateClass::SystemStateEnum; #endif // TYPES_H
Class with enum property
#ifndef CTRL_H #define CTRL_H #include <QObject> #include "Types.h" class Ctrl : public QObject { Q_OBJECT public: Ctrl() {}; ~Ctrl() = default; Q_PROPERTY(SystemState state READ state NOTIFY stateChanged) SystemState state() { return m_state; } signals: void stateChanged(SystemState); private: SystemState m_state = SystemState::MainView; }; #endif // CTRL_H
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "Ctrl.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; qRegisterMetaType<SystemState>("SystemState"); engine.rootContext()->setContextProperty("ctrl", new Ctrl()); qmlRegisterUncreatableType<SystemStateClass>("App.Types", 1, 0, "SystemState", "Not creatable as it is an enum type"); engine.load("qrc:/main.qml"); return app.exec(); }
main.qml
import QtQuick 2.14 import QtQuick.Window 2.14 import App.Types 1.0 Window { visible: true width: 640 height: 480 title: qsTr("Test enum") Component.onCompleted: { console.log("ctrl.state:", ctrl.state) console.log("Enum value:", SystemState.MainView) console.log("Equals enum val:", (ctrl.state === SystemState.MainView)) console.log("Equals int:", (ctrl.state === 1)) } }
Output
qml: ctrl.state: MainView qml: Enum value: 1 qml: Equals enum val: false qml: Equals int: false
-
I solved it. The type used in the Q_PROPERTY must be stated explicitly as SystemStateClass::SystemStateEnum instead of using using-declaration (or typedef) SystemState.
Q_PROPERTY(SystemStateClass::SystemStateEnum state READ state NOTIFY stateChanged)
This will allow QML to interpret the enum as int and the output will be:
qml: ctrl.state: 1 qml: Enum value: 1 qml: Equals enum val: true qml: Equals int: true
The using-declaration SystemState can be used in all other parts of C++ code except in Q_PROPERTY.