Search code examples
c++qtqml

How to correctly use c++ enum class into QML?


I have little Qt/QML project, where I try to use c++ enum class.

main.cpp

int main(int argc, char *argv[])
{
    qmlRegisterUncreatableType<shop::FruitShop>("FruitShop", 1, 0, "FruitShop", QStringLiteral("Sume shop"));
    qRegisterMetaType<shop::FruitShop::Fruit>();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    shop::FruitSetter setter;
    engine.rootContext()->setContextProperty("_fruitSetter", &setter);
...

fruitshop.h

#include <QObject>

namespace shop {
class FruitShop : public QObject
{
    Q_OBJECT
public:
    enum class Fruit
    {
        Orange,
        Apple,
        Pear
    };
    Q_ENUM(Fruit)
    explicit FruitShop(QObject *parent = nullptr);
};
} // namespace shop

fruitsetter.h

#include <QObject>
#include "fruitshop.h"

namespace shop {
class FruitSetter : public QObject
{
    Q_OBJECT
public:
    explicit FruitSetter(QObject *parent = nullptr);
    Q_INVOKABLE void setFruit(FruitShop::Fruit fruit);
};
} // namespace shop

main.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

import FruitShop 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Button {
        anchors.centerIn: parent
        text: "Set Fruit"
        onClicked: {_fruitSetter.setFruit(FruitShop.Apple)}
    }
}

If I use without namespace shop all is ok. But if I use as I present in code above I got error

qrc:/main.qml:16: Error: Unknown method parameter type: FruitShop::Fruit

How can I resolve this problem?


Solution

  • You have to include the namespace in the signature of the Q_INVOKABLE as well:

    Q_INVOKABLE void setFruit(shop::FruitShop::Fruit fruit)
    

    It's just the same as with Q_PROPERTY's, as explained here: https://wiki.qt.io/How_to_use_a_C_class_declared_in_a_namespace_with_Q_PROPERTY_and_QML

    The normal C++ rules that the class is in the same namespace don't work here, probably because of the way the Qt MOC tool handles this.