Q_ENUMS are "undefined" in QML?

c++, qml, qt, qt-signals, qtquick2

Solution

Your problem is not the exposure of the enum, but the fact that you have a leading underscore. Once you remove that, it will work.

You need to start the enum value with uppercase letter. Some rule is necessary to distinguish enums from attached properties from enums. Leading uppercase will refer to enums, and the rest for attached properties (or undefined if not set).

Admittedly, there is also a warning in Qt itself because if you try to assign that enum value to an int or var property, you are currently not getting a warning, and having discussed that issue a little bit with the current maintainer, it seems to be a bug which will be fixed later on.

See the working code below with the correspondigly proposed solution:

main.cpp

#include <QQuickView>
#include <QQuickItem>

#include <QGuiApplication>

#include <QUrl>

class UI : public QQuickItem {
    Q_OBJECT
    Q_ENUMS(ObjectType)
public:
enum ObjectType {
        Root = 0,
        _Block
    };
};

#include "main.moc"

int main(int argc, char **argv)
{
    QGuiApplication guiApplication(argc, argv);
    qmlRegisterType<UI>("Nodes", 1, 0, "UI");
    QQuickView *view = new QQuickView;
    view->setSource(QUrl::fromLocalFile("main.qml"));
    view->show();
    return guiApplication.exec();
}

main.qml

import Nodes 1.0
import QtQuick 2.0

Rectangle {
    id: button
    width: 500; height: 500

    MouseArea {
        anchors.fill: parent
        onClicked: console.log(UI.Root)
    }
}

main.pro

TEMPLATE = app
TARGET = main
QT += quick
SOURCES += main.cpp

Build and Run

qmake && make && ./main

Output

0

Problem

Enums are not working out for me. - I have registered them with `Q_ENUMS()` - I did not forget the `Q_OBJECT` macro - the type is registered using `qmlRegisterType()` - the module is imported in QML In short, everything is "by-the-book" but for some reason I continue getting `undefined` for each and every enum in QML. Am I missing something? ``` class UI : public QQuickItem { Q_OBJECT Q_ENUMS(ObjectType) public: enum ObjectType { _Root = 0, _Block }; ... }; ``` ... ``` qmlRegisterType<UI>("Nodes", 1, 0, "UI"); ``` ... ``` import Nodes 1.0 ... console.log(UI._Root) // undefined ``` EDIT: Also note that the registered enums are indeed available to use for the metasystem, for some reason they do not work in QML. UPDATE: I just found this bug: https://bugreports.qt.io/browse/QTBUG-33248 But unlike that bug my root component is a bare `UI` not a custom element with `UI` as its root. Turns out that it is actually possible to use enum values form QML in `console.log()`, the following code is actually working. ``` class A : public QObject { Q_OBJECT Q_ENUMS(EA) public: enum EA { EA_NULL = 0, EA_ONE }; }; class B : public A { Q_OBJECT Q_ENUMS(EB) public: enum EB { EA_TWO = 2, EA_THREE }; }; #include "main.moc" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<A>("test", 1, 0, "A"); qmlRegisterType<B>("test", 1, 0, "B"); QtQuick2ApplicationViewer viewer; viewer.setMainQmlFile(QStringLiteral("qml/enums/main.qml")); viewer.showExpanded(); return app.exec(); } ``` and... ``` Component.onCompleted: { console.log(A.EA_NULL) console.log(A.EA_ONE) console.log(B.EA_NULL) console.log(B.EA_ONE) console.log(B.EA_TWO) console.log(B.EA_THREE) } ``` Output is: ``` 0 1 0 1 2 3 ``` So I guess there is another problem besides "you are not using it correctly"... It might have to do with the bug I mentioned above, and the fact that when I instantiate the `UI` element, I actually instantiate a QML component which is a tree of objects with the `UI` as the root. While this doesn't prove to be any problem for working with pointers from C++ with the full QML objects, it does seem to mess enums for some reason.

Original source