Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Cannot compare C++ enum in QML
Forum Updated to NodeBB v4.3 + New Features

Cannot compare C++ enum in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
2 Posts 1 Posters 1.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rdeem
    wrote on last edited by
    #1

    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
    
    R 1 Reply Last reply
    0
    • R rdeem

      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
      
      R Offline
      R Offline
      rdeem
      wrote on last edited by
      #2

      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.

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved