4

I have delegate component in a separate qml file, in which I'd like to have a property which is an enum class type coming from a c++ QObject. Is this possible?

Here is a Minimum (non)Working Example:

card.h

#include <QObject>

class Card : public QObject
{
    Q_OBJECT
public:
    explicit Card(QObject *parent = 0);

    enum class InGameState {
        IDLE,
        FLIPPED,
        HIDDEN
    };
    Q_ENUM(InGameState)

private:
    InGameState mState;
};
Q_DECLARE_METATYPE(Card::InGameState)

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "card.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<Card::InGameState>("com.memorygame.ingamestate", 1, 0, "InGameState");
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

testcard.qml

import QtQuick 2.0
import com.memorygame.ingamestate 1.0

Item {
    property InGameState state

    Rectangle {
        id: dummy
        width: 10
    }
}

Compiler error I get:

D:\Programs\Qt\Qt5.7.0\5.7\mingw53_32\include\QtQml\qqml.h:89: error: 'staticMetaObject' is not a member of 'Card::InGameState' const char *className = T::staticMetaObject.className(); \

The enum class in not a QObject, that's why I get this error, right? But shouldn't Q_ENUM macro makes it available in the MetaSystem?

Could you please help me with this out? I could drop enum class, and change it to enum, and use an int property in qml, but I would like to use c++11 features.

speter
  • 49
  • 2
  • 7

1 Answers1

3

According to the documentation,

To use a custom enumeration as a data type, its class must be registered and the enumeration must also be declared with Q_ENUM() to register it with Qt's meta object system.

So you need to register your class Card instead of the enum InGameState:

qmlRegisterType<Card>("com.memorygame.card", 1, 0, "Card");

Additionally:

The enumeration type is a representation of a C++ enum type. It is not possible to refer to the enumeration type in QML itself; instead, the int or var types can be used when referring to enumeration values from QML code.

For example, in your case, the enum should be use as follows:

import QtQuick 2.0
import com.memorygame.card 1.0

Item {
    property int state: Card.FLIPPED

    Rectangle {
        id: dummy
        width: 10
    }
}
Tarod
  • 6,732
  • 5
  • 44
  • 50
  • Hey Tarod! Thank you for your help! (actually registering Card class was done in my real project, but sorry for not mentioning it the original post) The really big help was pointing out that QML won't ever have a custom property type of an enum class, which was my original (false) idea. I managed to use int, and var also in signal-slots, respectively with int, and QVariant parameter types on the receiving side. – speter Dec 08 '16 at 10:01
  • @speter Great! Thanks to you. Happy coding :) – Tarod Dec 08 '16 at 11:18