Search code examples
qtqmlqt-quickqenum

How to access a Q_ENUM declared in C++ class from QML?


I have a Q_ENUM declared in MyClass like below:

class MyClass {
public:
    enum Enum_Test {
        eTestA,
        eTestB
    }
    Q_ENUM(Enum_Test)

    Q_OBJECT
    Q_PROPERTY(MyClass::Enum_Test enumTest READ GetEnumTest WRITE SetEnumTest )
}

I have MyClass registered on the QML side like below and able to access it.

auto my_class = std::make_shared<MyClass>();
qmlRegisterUncreatableType<MyClass>("MyClass", 1,0, "MyClass","Cannot create type MyClass in QML");
rootContext()->setContextProperty("my_class", my_class.get());

How do I access Q_ENUM Enum_Test from QML?


Solution

  • Your class needs two adjustments.

    1. as pointed out by JarMan, it needs a metaObject, which can be obtained by deriving from QObject and adding Q_OBJECT:

      class MyClass : public QObject
      {
          Q_OBJECT
          ...
      };
      

      Actually, it would also be possible to use Q_GADGET but you already seem to lean towards Q_OBJECT. But, as requested, here we go:

      class MyClass
      {
        Q_GADGET
      
      public:
        enum Enum_Test {
            ETestA,
            ETestB
        };
        Q_ENUM(Enum_Test)
      };
      

      Keep in mind that Q_GADGET cannot have signals, so I left out the property and only have this class as "enum-placeholder".

    2. The enum value names need to be capitalized:

      enum Enum_Test {
          ETestA,
          ETestB
      };
      Q_ENUM(Enum_Test)
      

    Then you can use it in QML as:

         QtObject {
             property int myEnumVal: MyClass.ETestA
         }
    

    Note that support for enums is somewhat limited because the mix with JavaScript. The values will be converted to integers. Also, when used in a JavaScript switch-statement, typo's will not be warned about by QtCreator (assuming version 4.14)