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. How to expose enum in class to QML
Forum Updated to NodeBB v4.3 + New Features

How to expose enum in class to QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 4 Posters 2.4k Views 1 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.
  • fcarneyF Offline
    fcarneyF Offline
    fcarney
    wrote on last edited by fcarney
    #2

    Register the type:

    qmlRegisterType<LanguageSelector>("LanguageSelectors",1,0,"LanguageSelector");
    

    // or qmlRegisterTypeNotAvailable qmlRegisterUncreatableType if you don't want to instantiate in QML

    Then in qml:

    import LanguageSelectors 1.0
    
    ...
    
    languageSelector.changeLanguage(LanguageSelector.german)
    

    C++ is a perfectly valid school of magic.

    J.HilkJ 1 Reply Last reply
    1
    • fcarneyF fcarney

      Register the type:

      qmlRegisterType<LanguageSelector>("LanguageSelectors",1,0,"LanguageSelector");
      

      // or qmlRegisterTypeNotAvailable qmlRegisterUncreatableType if you don't want to instantiate in QML

      Then in qml:

      import LanguageSelectors 1.0
      
      ...
      
      languageSelector.changeLanguage(LanguageSelector.german)
      
      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #3

      @fcarney I think thats the wrong register call. Enums aren't types!

      qmlRegisterUncreatableType< LanguageSelector >("LanguageSelectors",1,0,"LanguageSelector","Enum is not a type");
      

      it says so in the documentation 😉
      https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableType


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      GrecKoG fcarneyF 2 Replies Last reply
      2
      • J.HilkJ J.Hilk

        @fcarney I think thats the wrong register call. Enums aren't types!

        qmlRegisterUncreatableType< LanguageSelector >("LanguageSelectors",1,0,"LanguageSelector","Enum is not a type");
        

        it says so in the documentation 😉
        https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableType

        GrecKoG Offline
        GrecKoG Offline
        GrecKo
        Qt Champions 2018
        wrote on last edited by
        #4

        @J-Hilk That's the correct register call but the error message you put is misleading.

        This would appear while trying to do LanguageSelector {} in QML, so the link with Enum is not really apparent. Just mention that LanguageSelector is not instantiable in QML code.

        J.HilkJ 1 Reply Last reply
        1
        • GrecKoG GrecKo

          @J-Hilk That's the correct register call but the error message you put is misleading.

          This would appear while trying to do LanguageSelector {} in QML, so the link with Enum is not really apparent. Just mention that LanguageSelector is not instantiable in QML code.

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #5

          @GrecKo I actually have that from here:
          https://doc.qt.io/archives/qt-5.10/qtbluetooth-heartrate-game-main-cpp.html

          and it's still in the newest documentation

          https://code.qt.io/cgit/qt/qtconnectivity.git/tree/examples/bluetooth/heartrate-game/main.cpp?h=5.15


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          1
          • J.HilkJ J.Hilk

            @fcarney I think thats the wrong register call. Enums aren't types!

            qmlRegisterUncreatableType< LanguageSelector >("LanguageSelectors",1,0,"LanguageSelector","Enum is not a type");
            

            it says so in the documentation 😉
            https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableType

            fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by fcarney
            #6

            @J-Hilk said in How to expose enum in class to QML:

            Enums aren't types!

            Edit: I think I am slow this morning.

            Your right, it should be qmlRegisterUncreatableType

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            2
            • S Offline
              S Offline
              sandro4912
              wrote on last edited by sandro4912
              #7

              Thank you all for all the answers. I tried to go with the uncreateable type but I get an Error.

              Here is what I did:

              Change the enum names to uppercase (German, English, Spanish) because qml complains they have to be uppercase.

              In Cpp:

              qmlRegisterUncreatableType<LanguageSelector>(
                  "LanguageSelectors", 1, 0, "LanguageSelector",
                  "LanguageSelector is not instantiatable in QML");
              

              In QML:

              import LanguageSelectors 1.0
              
              Component.onCompleted: {
                      LanguageSelector.changeLanguage(LanguageSelector.German)
                  }
              

              This line gives me an error:

              TypeError: Property 'changeLanguage' of object [object Object] is not a function
              

              I don't get it why. In the class it is invokeable like this:

              class LanguageSelector : public QObject {
                  Q_OBJECT
              public:
                  enum class Language { German, English, Spanish };
                  Q_ENUM(Language)
              
                  explicit LanguageSelector(QObject *parent = nullptr);
              
                  Q_INVOKABLE void changeLanguage(Language newLanguage);
              //....
              
              private:
              //....
              signals:
                  void languageChanged();
              
              }
              

              A second concern. When I call changeLanguge in QML the signal "languageChanged". When that happends we need to call
              QQmlApplicationEngine::retranslate to retranslate the ui.

              Is that possible to connect to the uncreateable type?

              Before when i exposed it with the context I simply did:

                  QObject::connect(&languageSelector,
                  &LanguageSelector::languageChanged,
                                   &engine, &QQmlApplicationEngine::retranslate);
              

              Maybe for that I still have to create an object? Or is there annother way to call retranslate from QML when languageChanged is called in QML?

              Since I have the signal isn't it then a canidate for qmlRegisterSingletonInstance ?

              1 Reply Last reply
              0
              • S Offline
                S Offline
                sandro4912
                wrote on last edited by
                #8

                I could get it to work with the singleton approach:

                QScopedPointer<LanguageSelector> languageSelector(new LanguageSelector);
                
                //..
                
                
                qmlRegisterSingletonInstance<LanguageSelector>(
                    "LanguageSelectors", 1, 0, "LanguageSelector", languageSelector.get());
                
                
                //..
                
                QObject::connect(languageSelector.get(), &LanguageSelector::languageChanged,
                                 &engine, &QQmlApplicationEngine::retranslate);
                engine.load(url);
                

                In QML:

                import LanguageSelectors 1.0
                
                
                //....
                
                Component.onCompleted: {
                            showButtonsIfConditionsAreMet()
                            LanguageSelector.changeLanguage(LanguageSelector.German)
                }
                

                Now the only strange thing. I get a complain from QT Creator that it does not know the import:

                159964ab-1b2e-45da-9ab3-21d5176abda6-image.png

                Any way to get rid of that or is it like a bug in creator?

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #9

                  @sandro4912 said in How to expose enum in class to QML:

                  This class gets exposed to qml like this:
                  QQmlApplicationEngine engine;

                  auto context = engine.rootContext();
                  context->setContextProperty("languageSelector", &languageSelector);

                  In QML then I thought I could change the language like this (refering to the enum):
                  ToolButton {
                  //...
                  onClicked: languageSelector.changeLanguage(languageSelector.spanish)
                  }

                  Backup, I built upon the code above. I was using the languageSelector context property you set. Do not capitalize this object.

                  This code is not an error. languageSelector.changeLanguage should appear like this because your context property cannot be capitalized.
                  LanguageSelector.german is capitalized because you are using it as a QML type. Don't mix this up.

                  import LanguageSelectors 1.0
                  
                  ...
                  
                  languageSelector.changeLanguage(LanguageSelector.german)
                  

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  1
                  • GrecKoG Offline
                    GrecKoG Offline
                    GrecKo
                    Qt Champions 2018
                    wrote on last edited by
                    #10

                    Note that qmlRegisterSingletonInstance should be preferred over setContextProperty for new code.

                    @J-Hilk said in How to expose enum in class to QML:

                    @GrecKo I actually have that from here:
                    https://doc.qt.io/archives/qt-5.10/qtbluetooth-heartrate-game-main-cpp.html

                    and it's still in the newest documentation

                    https://code.qt.io/cgit/qt/qtconnectivity.git/tree/examples/bluetooth/heartrate-game/main.cpp?h=5.15

                    What a weird place to copy code from :) Still, it doesn't really make sense even there.

                    1 Reply Last reply
                    1
                    • S Offline
                      S Offline
                      sandro4912
                      wrote on last edited by sandro4912
                      #11

                      Maybe I was not clear in the last post. I got rid of context property complete and only registered the type with qmlRegisterSingletonInstance.

                      Now just wonder why creator complains about the import even if all the code works fine.

                      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