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. Get all enum value names from C++ enum definition
Forum Updated to NodeBB v4.3 + New Features

Get all enum value names from C++ enum definition

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 698 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.
  • SebastianMS Offline
    SebastianMS Offline
    SebastianM
    wrote on last edited by
    #1

    Hi,
    System spec: Windows 10, Qt 6.9, mingw64 13.10, Qt Creator 17.0.1
    Classic C++ enum side declaration.

    #include <QObject>
    #include <QtQml/qqml.h>
    
    class BackgroundType : public QObject
    {
        Q_OBJECT
        QML_ELEMENT
        QML_UNCREATABLE("BackgroundType is not creatable - use enum values only")
    
    public:
        explicit BackgroundType(QObject *parent = nullptr) : QObject(parent) {}
    
        enum Value {
            Basic,
            Upper,
            VIP
        };
        Q_ENUM(Value)
    };
    

    This class is NOT compiled with qt_add_qml_module. So I used

        qmlRegisterUncreatableType<BackgroundType>("InfModule", 1, 0,
                                              "BackgroundType",
                                              "BackgroundTypeis not creatable - use enum values only");
    

    Now, In QML side I would like to get list of all value names. For test purpose to scroll through them in combobox and check if all is fine.
    Q_PROPERTY with static QStringList, Q_INVOKABLE returning QStringList - none of them work.
    How to achive enum availabilty of uncreatable type with ability to print all enum values names?

    1 Reply Last reply
    0
    • SebastianMS Offline
      SebastianMS Offline
      SebastianM
      wrote on last edited by SebastianM
      #4

      Partial solution which I found is to register this enum C++ class as creatable.
      Then in point where I need value names - is to call is JS section

      var obj = Qt.createQmlObject('import InfModule1.0; BackgroundType {}', parent); 
      obj.names();
      
      1 Reply Last reply
      0
      • B Offline
        B Offline
        Bob64
        wrote on last edited by
        #2

        I don't know if there is a simpler way that is already built in, but you could look into using QMetaEnum on the C++ side and expose it to QML.

        1 Reply Last reply
        1
        • SebastianMS Offline
          SebastianMS Offline
          SebastianM
          wrote on last edited by SebastianM
          #3

          To be clear - I would like to call from QML side BackgroundType.getValueNames(); and receive QStringList("Basic", "Upper", "Vip").
          Or my own QStrings mapping - like QStringList("Basic Background", "Upper Level Background", "Vip Ultimate Background").

          PS:

              Q_INVOKABLE QStringList fun() { return {"Basic"), "Upper", "VIP"}; }
          

          it doesn't matter if it's registered with qmlRegisterType or qmlRegisterUncreatableType or if I remove QML_UNCREATABLE from dla in results - QML engine warns with
          TypeError: Property 'names' of object InfModule/BackgroundType is not a function

          1 Reply Last reply
          0
          • SebastianMS Offline
            SebastianMS Offline
            SebastianM
            wrote on last edited by SebastianM
            #4

            Partial solution which I found is to register this enum C++ class as creatable.
            Then in point where I need value names - is to call is JS section

            var obj = Qt.createQmlObject('import InfModule1.0; BackgroundType {}', parent); 
            obj.names();
            
            1 Reply Last reply
            0
            • SebastianMS SebastianM has marked this topic as solved on
            • SebastianMS Offline
              SebastianMS Offline
              SebastianM
              wrote on last edited by SebastianM
              #5

              Other solution is ... to create attached properties

              namespace MessageTypes {
                  Q_NAMESPACE
                  QML_ELEMENT
              
                  enum class Type {
                      None,
                      SessionOpened,
                      ConfigurationExternal,
                      ConfigurationGet,
                  };
                  Q_ENUM_NS(Type)
              
                  inline static const QMap<Type, QString>& typeToString() {
                      static const QMap<Type, QString> map = {
                          {Type::None, "None"},
                          {Type::SessionOpened, "SessionOpened"},
                          {Type::ConfigurationExternal, "configuration/external"},
                          {Type::ConfigurationGet, "configuration/get"},
                      };
                      return map;
                  }
              
                  inline static const QMap<QString, Type>& stringToType() {
                      static QMap<QString, Type> reverseMap = []() {
                          QMap<QString, Type> map;
                          for (auto it = MessageTypes::typeToString().cbegin();
                               it != MessageTypes::typeToString().cend(); ++it) {
                              map.insert(it.value(), it.key());
                          }
                          return map;
                      }();
                      return reverseMap;
                  }
              }
              
              // Attached object type - contains the utility methods
              class MessageTypesAttached : public QObject
              {
                  Q_OBJECT
                  QML_ANONYMOUS  // Not directly instantiable
              
              public:
                  explicit MessageTypesAttached(QObject *parent = nullptr)
                      : QObject(parent)
                  {}
              
                  // Helper functions
                  Q_INVOKABLE inline static QString toString(MessageTypes::Type type) {
                      return MessageTypes::typeToString().value(type, QString());
                  }
              
                  Q_INVOKABLE inline static MessageTypes::Type fromString(const QString& str, MessageTypes::Type defaultValue = MessageTypes::Type::None) {
                      return MessageTypes::stringToType().value(str, defaultValue);
                  }
              
                  Q_INVOKABLE inline static QStringList getAllTypesName() {    
                          return MessageTypes::typeToString().values();    
                  }
              }  
                  
              
              // Attaching type - provides access to the attached object
              class MessageTypesUtils : public QObject
              {
                  Q_OBJECT
                  QML_ELEMENT
                  QML_UNCREATABLE("MessageTypesUtils is only for attached properties")
                  QML_ATTACHED(MessageTypesAttached)
              
              public:
                  explicit MessageTypesUtils(QObject *parent = nullptr)
                      : QObject(parent)
                  {}
              
                  // Required static method for attached properties
                  static MessageTypesAttached *qmlAttachedProperties(QObject *object)
                  {
                      return new MessageTypesAttached(object);
                  }
              };
              
              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