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. using C++ classes and structs in QML
Forum Update on Monday, May 27th 2025

using C++ classes and structs in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
30 Posts 9 Posters 5.3k Views
  • 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.
  • J J.Hilk
    9 Oct 2023, 08:15

    @mzimmers a struct and a class are literally the same in c++ 😉

    did you forget to add Q_GADGET in your struct ?

    M Offline
    M Offline
    mzimmers
    wrote on 9 Oct 2023, 13:07 last edited by mzimmers 10 Sept 2023, 13:10
    #8

    @J-Hilk said in using C++ class in QML:

    did you forget to add Q_GADGET in your struct ?

    No, but I must be doing something just as silly. I even converted my struct to a class, so now I have:

    class MyStruct {
        Q_GADGET
        QML_ELEMENT
        Q_PROPERTY(int myInt MEMBER m_myInt)
        int m_myInt = 55;
    public:
        MyStruct() {}
    };
    Q_DECLARE_METATYPE(MyStruct)
    

    along with:

    class MyClass : public QObject {
        Q_OBJECT
        QML_ELEMENT
        Q_PROPERTY(int classInt MEMBER m_classInt NOTIFY classIntChanged)
        int m_classInt = 55;
    signals:
        Q_INVOKABLE void classIntChanged();
    public:
        MyClass() {}
    };
    Q_DECLARE_METATYPE(MyClass)
    

    and in main.cpp:

        qmlRegisterType<MyStruct>("MyStruct", 1, 0, "MyStruct");
        qmlRegisterType<MyClass>("MyClass", 1, 0, "MyClass");
    

    The first line produces a runtime error: "Invalid QML element name "MyStruct"; value type names should begin with a lowercase letter" while the second line works fine.

    Somewhere, I'm overlooking one of the magic Qt macros, but I sure can't see it.

    EDIT:

    It works if I subclass MyStruct from QObject. This is OK for this little example, but has implications for my real project. Somehow I'm not getting Q_GADGET properly set up.

    1 Reply Last reply
    0
    • J J.Hilk
      9 Oct 2023, 08:15

      @mzimmers a struct and a class are literally the same in c++ 😉

      did you forget to add Q_GADGET in your struct ?

      S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 9 Oct 2023, 18:37 last edited by
      #9

      @J-Hilk said in using C++ classes and structs in QML:

      @mzimmers a struct and a class are literally the same in c++ 😉

      Nope, there's key difference: the former has everything public by default while the latter has everything private.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply 9 Oct 2023, 20:53
      0
      • S SGaist
        9 Oct 2023, 18:37

        @J-Hilk said in using C++ classes and structs in QML:

        @mzimmers a struct and a class are literally the same in c++ 😉

        Nope, there's key difference: the former has everything public by default while the latter has everything private.

        M Offline
        M Offline
        mzimmers
        wrote on 9 Oct 2023, 20:53 last edited by mzimmers 10 Oct 2023, 13:11
        #10

        @SGaist true enough, but I think I've obviated that difference with my use of the "public" keyword:
        EDIT: I neglected to point out that the Q_GADGET macro causes everything declared after it to be private unless explicitly declared to the contrary, hence my use of public.

        struct MyStruct {
            Q_GADGET
        public:
            QML_ELEMENT
            QML_VALUE_TYPE(myStruct)
            Q_PROPERTY(int myInt MEMBER m_myInt)
            int m_myInt = 55;
            MyStruct() {}
        };
        Q_DECLARE_METATYPE(MyStruct)
        

        With this declaration, I get a build error on this line:

        property myStruct myStruct1: myStruct {
        

        "error: Expected type name"

        J 1 Reply Last reply 9 Oct 2023, 23:11
        0
        • M mzimmers
          9 Oct 2023, 20:53

          @SGaist true enough, but I think I've obviated that difference with my use of the "public" keyword:
          EDIT: I neglected to point out that the Q_GADGET macro causes everything declared after it to be private unless explicitly declared to the contrary, hence my use of public.

          struct MyStruct {
              Q_GADGET
          public:
              QML_ELEMENT
              QML_VALUE_TYPE(myStruct)
              Q_PROPERTY(int myInt MEMBER m_myInt)
              int m_myInt = 55;
              MyStruct() {}
          };
          Q_DECLARE_METATYPE(MyStruct)
          

          With this declaration, I get a build error on this line:

          property myStruct myStruct1: myStruct {
          

          "error: Expected type name"

          J Offline
          J Offline
          jsulm
          Lifetime Qt Champion
          wrote on 9 Oct 2023, 23:11 last edited by
          #11

          @mzimmers Isn't the name of the struct MyStruct and not myStruct?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          M 1 Reply Last reply 9 Oct 2023, 23:28
          0
          • J jsulm
            9 Oct 2023, 23:11

            @mzimmers Isn't the name of the struct MyStruct and not myStruct?

            M Offline
            M Offline
            mzimmers
            wrote on 9 Oct 2023, 23:28 last edited by
            #12

            @jsulm if you're referring to the QML line of code, I get an error if I try to use "MyStruct:"
            Screenshot 2023-10-09 162726.png

            J 1 Reply Last reply 10 Oct 2023, 05:47
            0
            • M mzimmers
              9 Oct 2023, 23:28

              @jsulm if you're referring to the QML line of code, I get an error if I try to use "MyStruct:"
              Screenshot 2023-10-09 162726.png

              J Offline
              J Offline
              J.Hilk
              Moderators
              wrote on 10 Oct 2023, 05:47 last edited by
              #13

              @mzimmers can you show the full (copy pasted) content of your qml file ?
              we haven't seen that and maybe its a simple error there

              @SGaist said in using C++ classes and structs in QML:

              Nope, there's key difference: the former has everything public by default while the latter has everything private

              mäh, tomato/tomato, it changes the default but you can still declare private /prublic manually


              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.

              M 1 Reply Last reply 10 Oct 2023, 13:17
              0
              • J J.Hilk
                10 Oct 2023, 05:47

                @mzimmers can you show the full (copy pasted) content of your qml file ?
                we haven't seen that and maybe its a simple error there

                @SGaist said in using C++ classes and structs in QML:

                Nope, there's key difference: the former has everything public by default while the latter has everything private

                mäh, tomato/tomato, it changes the default but you can still declare private /prublic manually

                M Offline
                M Offline
                mzimmers
                wrote on 10 Oct 2023, 13:17 last edited by
                #14

                @J-Hilk sure - I'll post from the top to the point of errors (I'm skipping the Labels that I use for telltales):

                import QtQuick
                import QtQuick.Controls
                import QtQuick.Layouts
                import QtQuick.Window
                
                import MyStruct
                
                Window {
                    id: mainWindow
                    width: 640
                    height: 480
                    visible: true
                
                    property MyStruct myStruct1: MyStruct {
                        myInt: 100
                    }
                
                    MyStruct {
                        id: myStruct2
                        myInt: 200
                    }
                

                While I'm at it, here's my main.cpp ("struct" is the project name):

                #include <QGuiApplication>
                #include <QQmlContext>
                #include <QQmlApplicationEngine>
                
                #include "mystruct.h"
                #include "myclass.h"
                
                int main(int argc, char *argv[])
                {
                    QGuiApplication app(argc, argv);
                    QQmlApplicationEngine engine;
                
                    qmlRegisterType<MyStruct>("MyStruct", 1, 0, "MyStruct"); // tried "myStruct" too
                    qmlRegisterType<MyClass>("MyClass", 1, 0, "MyClass");
                
                    QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
                        &app, []() { QCoreApplication::exit(-1); },
                        Qt::QueuedConnection);
                
                    engine.loadFromModule("struct", "Main");
                
                    return app.exec();
                }
                
                J 1 Reply Last reply 10 Oct 2023, 13:27
                0
                • M mzimmers
                  10 Oct 2023, 13:17

                  @J-Hilk sure - I'll post from the top to the point of errors (I'm skipping the Labels that I use for telltales):

                  import QtQuick
                  import QtQuick.Controls
                  import QtQuick.Layouts
                  import QtQuick.Window
                  
                  import MyStruct
                  
                  Window {
                      id: mainWindow
                      width: 640
                      height: 480
                      visible: true
                  
                      property MyStruct myStruct1: MyStruct {
                          myInt: 100
                      }
                  
                      MyStruct {
                          id: myStruct2
                          myInt: 200
                      }
                  

                  While I'm at it, here's my main.cpp ("struct" is the project name):

                  #include <QGuiApplication>
                  #include <QQmlContext>
                  #include <QQmlApplicationEngine>
                  
                  #include "mystruct.h"
                  #include "myclass.h"
                  
                  int main(int argc, char *argv[])
                  {
                      QGuiApplication app(argc, argv);
                      QQmlApplicationEngine engine;
                  
                      qmlRegisterType<MyStruct>("MyStruct", 1, 0, "MyStruct"); // tried "myStruct" too
                      qmlRegisterType<MyClass>("MyClass", 1, 0, "MyClass");
                  
                      QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
                          &app, []() { QCoreApplication::exit(-1); },
                          Qt::QueuedConnection);
                  
                      engine.loadFromModule("struct", "Main");
                  
                      return app.exec();
                  }
                  
                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 10 Oct 2023, 13:27 last edited by
                  #15

                  don't know if that changed with Qt6 but shouldn't this

                  @mzimmers said in using C++ classes and structs in QML:

                  import MyStruct

                  be

                  import MyStruct 1.0

                  ?


                  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.

                  M 1 Reply Last reply 10 Oct 2023, 13:29
                  0
                  • J J.Hilk
                    10 Oct 2023, 13:27

                    don't know if that changed with Qt6 but shouldn't this

                    @mzimmers said in using C++ classes and structs in QML:

                    import MyStruct

                    be

                    import MyStruct 1.0

                    ?

                    M Offline
                    M Offline
                    mzimmers
                    wrote on 10 Oct 2023, 13:29 last edited by mzimmers 10 Oct 2023, 13:43
                    #16

                    @J-Hilk that doesn't seem to matter any more. If you try to import a version number that's higher than what you registered, you'll get a runtime error, but that's about it.

                    This is just nuts, though. In main.cpp, this line:

                    qmlRegisterType<MyStruct>("myStruct", 1, 0, "myStruct");
                    

                    Produces a warning from the editor/code model/whatever that QML types must begin with uppercase. Plus it won't build, giving an error at my QML declaration "error: Expected type name".

                    But if I modify that line in main.cpp to:

                    qmlRegisterType<MyStruct>("myStruct", 1, 0, "MyStruct"); // tried "myStruct" too
                    

                    and then I have to change my Main.qml to:

                        property MyStruct myStruct1: MyStruct {
                    

                    I get a runtime error: "qt.qml.typeregistration: Invalid QML element name "MyStruct"; value type names should begin with a lowercase letter"

                    It's almost as though I shouldn't be registering my struct, though I don't know what the alternative might be.

                    L 1 Reply Last reply 10 Oct 2023, 14:22
                    1
                    • M mzimmers
                      10 Oct 2023, 13:29

                      @J-Hilk that doesn't seem to matter any more. If you try to import a version number that's higher than what you registered, you'll get a runtime error, but that's about it.

                      This is just nuts, though. In main.cpp, this line:

                      qmlRegisterType<MyStruct>("myStruct", 1, 0, "myStruct");
                      

                      Produces a warning from the editor/code model/whatever that QML types must begin with uppercase. Plus it won't build, giving an error at my QML declaration "error: Expected type name".

                      But if I modify that line in main.cpp to:

                      qmlRegisterType<MyStruct>("myStruct", 1, 0, "MyStruct"); // tried "myStruct" too
                      

                      and then I have to change my Main.qml to:

                          property MyStruct myStruct1: MyStruct {
                      

                      I get a runtime error: "qt.qml.typeregistration: Invalid QML element name "MyStruct"; value type names should begin with a lowercase letter"

                      It's almost as though I shouldn't be registering my struct, though I don't know what the alternative might be.

                      L Offline
                      L Offline
                      lemons
                      wrote on 10 Oct 2023, 14:22 last edited by
                      #17

                      @mzimmers
                      I thought the Q_GADGET macro is used for meta-types only, which can't be instantiated from QML.
                      To be used e.g. if the struct is a property of an QObject derived class, which is somehow accessible in QML (either passed through C++ or created in QML).
                      Allows you to use e.g. Q_PROPERTY macros, without the QObject overhead.

                      To be creatable from QML you need a derived class from QObject, so the Q_GADGET macro is not sufficient, as it is missing e.g. the signals and slots of the QObject class.

                      Note: I can be totally wrong / outdated, but this is how I was thinking and using it all the time :D

                      J 1 Reply Last reply 10 Oct 2023, 14:36
                      1
                      • L lemons
                        10 Oct 2023, 14:22

                        @mzimmers
                        I thought the Q_GADGET macro is used for meta-types only, which can't be instantiated from QML.
                        To be used e.g. if the struct is a property of an QObject derived class, which is somehow accessible in QML (either passed through C++ or created in QML).
                        Allows you to use e.g. Q_PROPERTY macros, without the QObject overhead.

                        To be creatable from QML you need a derived class from QObject, so the Q_GADGET macro is not sufficient, as it is missing e.g. the signals and slots of the QObject class.

                        Note: I can be totally wrong / outdated, but this is how I was thinking and using it all the time :D

                        J Offline
                        J Offline
                        JoeCFD
                        wrote on 10 Oct 2023, 14:36 last edited by JoeCFD 10 Oct 2023, 14:39
                        #18

                        @lemons said in using C++ classes and structs in QML:

                        Q_GADGET macro

                        Lemons seems right.

                        In QML (Qt Meta-Object Language), the Q_GADGET macro is typically used with C++ classes to create non-instantiable classes that can be registered with the Qt meta-object system. These classes are similar to Q_OBJECT classes but cannot have signals, slots, or properties. They are often used for data-only structures that need to be exposed to QML.

                        I use upper case for my class registration in qmlRegisterType without issues. I guess lower case is needed in app_engine->rootContext()->setContextProperty( ... );

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          GrecKo
                          Qt Champions 2018
                          wrote on 10 Oct 2023, 14:45 last edited by GrecKo 10 Oct 2023, 14:58
                          #19

                          You can now instantiate Gadgets from QML with undocumented macros (so maybe don't use it).

                          Use QML_VALUE_TYPE(typeName) with a lower case name like you currently do.
                          Then you can add QML_CONSTRUCTIBLE_VALUE or QML_STRUCTURED_VALUE (even both).

                          QML_CONSTRUCTIBLE_VALUE will call a user defined constructor

                          if you have Q_INVOKABLE MyStruct(int foo) : m_myInt{foo} {}
                          then doing property myStruct myStruct1: 42 will call the constructor with 42 as the foo param

                          QML_STRUCTURED_VALUE will assign properties depending on the js object you passed in QML.

                          property myStruct myStruct1: ({myInt: 42}) will create a default constructed MyStruct and assign its myInt property to 42.

                          Note that the type should always be default constructible.

                          EDIT: Note that you don't have to use QML_ELEMENT, Q_DECLARE_METATYPE or qmlRegisterType if you use Q_GADGET and QML_VALUE_TYPE.

                          M L 2 Replies Last reply 10 Oct 2023, 15:23
                          3
                          • G GrecKo
                            10 Oct 2023, 14:45

                            You can now instantiate Gadgets from QML with undocumented macros (so maybe don't use it).

                            Use QML_VALUE_TYPE(typeName) with a lower case name like you currently do.
                            Then you can add QML_CONSTRUCTIBLE_VALUE or QML_STRUCTURED_VALUE (even both).

                            QML_CONSTRUCTIBLE_VALUE will call a user defined constructor

                            if you have Q_INVOKABLE MyStruct(int foo) : m_myInt{foo} {}
                            then doing property myStruct myStruct1: 42 will call the constructor with 42 as the foo param

                            QML_STRUCTURED_VALUE will assign properties depending on the js object you passed in QML.

                            property myStruct myStruct1: ({myInt: 42}) will create a default constructed MyStruct and assign its myInt property to 42.

                            Note that the type should always be default constructible.

                            EDIT: Note that you don't have to use QML_ELEMENT, Q_DECLARE_METATYPE or qmlRegisterType if you use Q_GADGET and QML_VALUE_TYPE.

                            M Offline
                            M Offline
                            mzimmers
                            wrote on 10 Oct 2023, 15:23 last edited by
                            #20

                            @GrecKo curiouser and curiouser.

                            My modified struct:

                            struct MyStruct {
                                QML_STRUCTURED_VALUE
                                QML_VALUE_TYPE(myStruct)
                                Q_PROPERTY(int myInt MEMBER m_myInt)
                                int m_myInt = 55;
                                MyStruct() {}
                            };
                            

                            my registration (in main.cpp):

                                qmlRegisterType<MyStruct>("myStruct", 1, 0, "MyStruct");
                            

                            and my QML:

                            property myStruct myStruct1: myStruct ({myInt: 100})
                            

                            produces a runtime error: "myStruct is not a type."

                            Isn't using QML_VALUE_TYPE intended to allow me to use "myStruct" in the QML?

                            G 1 Reply Last reply 10 Oct 2023, 16:14
                            0
                            • M mzimmers
                              10 Oct 2023, 15:23

                              @GrecKo curiouser and curiouser.

                              My modified struct:

                              struct MyStruct {
                                  QML_STRUCTURED_VALUE
                                  QML_VALUE_TYPE(myStruct)
                                  Q_PROPERTY(int myInt MEMBER m_myInt)
                                  int m_myInt = 55;
                                  MyStruct() {}
                              };
                              

                              my registration (in main.cpp):

                                  qmlRegisterType<MyStruct>("myStruct", 1, 0, "MyStruct");
                              

                              and my QML:

                              property myStruct myStruct1: myStruct ({myInt: 100})
                              

                              produces a runtime error: "myStruct is not a type."

                              Isn't using QML_VALUE_TYPE intended to allow me to use "myStruct" in the QML?

                              G Offline
                              G Offline
                              GrecKo
                              Qt Champions 2018
                              wrote on 10 Oct 2023, 16:14 last edited by
                              #21

                              As I said : you don't have to use qmlRegisterType. You do have to use Q_GADGET though.

                              And Q_GADGET adds a private: so you need to add back public:

                              struct MyStruct {
                                Q_GADGET
                                QML_VALUE_TYPE(myStruct)
                                QML_STRUCTURED_VALUE
                              
                                Q_PROPERTY(int myInt MEMBER m_myInt)
                              
                              public:
                                int m_myInt = 55;
                                MyStruct() {};
                              };
                              

                              and my QML:
                              property myStruct myStruct1: myStruct ({myInt: 100})

                              Did I write that? nope. The syntax for structured values is :

                              property myStruct myStruct1: ({myInt: 100})
                              

                              Ditch the myStruct on the right-hand side.

                              M 1 Reply Last reply 10 Oct 2023, 16:24
                              1
                              • G GrecKo
                                10 Oct 2023, 16:14

                                As I said : you don't have to use qmlRegisterType. You do have to use Q_GADGET though.

                                And Q_GADGET adds a private: so you need to add back public:

                                struct MyStruct {
                                  Q_GADGET
                                  QML_VALUE_TYPE(myStruct)
                                  QML_STRUCTURED_VALUE
                                
                                  Q_PROPERTY(int myInt MEMBER m_myInt)
                                
                                public:
                                  int m_myInt = 55;
                                  MyStruct() {};
                                };
                                

                                and my QML:
                                property myStruct myStruct1: myStruct ({myInt: 100})

                                Did I write that? nope. The syntax for structured values is :

                                property myStruct myStruct1: ({myInt: 100})
                                

                                Ditch the myStruct on the right-hand side.

                                M Offline
                                M Offline
                                mzimmers
                                wrote on 10 Oct 2023, 16:24 last edited by mzimmers 10 Oct 2023, 18:52
                                #22

                                @GrecKo oh, that is a thing of beauty.

                                Now...about QML_STRUCTURED_VALUE being an undocumented macro, as you said...is it safe to use? I did notice mention of it in a bug report, so maybe it's OK.

                                Thanks for the help.

                                EDIT: everything above works, but if possible, I'd like to directly access enums defined in the struct (actually, this was the original point behind this entire thread).

                                struct MyStruct {
                                    Q_GADGET
                                    QML_STRUCTURED_VALUE
                                    QML_VALUE_TYPE(myStruct)
                                    Q_PROPERTY(int myInt MEMBER m_myInt)
                                public:
                                    enum MyEnums {
                                        Enum0,
                                        Enum1,
                                        Enum2,
                                        Enum3
                                    } m_myEnums;
                                    Q_ENUM(MyEnums)
                                    int m_myInt = 55;
                                    MyStruct() {}
                                };
                                

                                This attempt doesn't work:

                                Label { text: "myStruct.Enum3: " + myStruct.Enum3 }
                                

                                (it doesn't work with "MyStruct" either.)

                                Can this be made to work? Thanks...

                                EDIT 2:

                                I have a workaround, which is to define my enums in a separate class and expose them to QML using the guidelines here, but if possible I'd prefer to avoid this level of indirection, and keep the enums in the struct.

                                G 1 Reply Last reply 11 Oct 2023, 07:55
                                0
                                • M mzimmers
                                  10 Oct 2023, 16:24

                                  @GrecKo oh, that is a thing of beauty.

                                  Now...about QML_STRUCTURED_VALUE being an undocumented macro, as you said...is it safe to use? I did notice mention of it in a bug report, so maybe it's OK.

                                  Thanks for the help.

                                  EDIT: everything above works, but if possible, I'd like to directly access enums defined in the struct (actually, this was the original point behind this entire thread).

                                  struct MyStruct {
                                      Q_GADGET
                                      QML_STRUCTURED_VALUE
                                      QML_VALUE_TYPE(myStruct)
                                      Q_PROPERTY(int myInt MEMBER m_myInt)
                                  public:
                                      enum MyEnums {
                                          Enum0,
                                          Enum1,
                                          Enum2,
                                          Enum3
                                      } m_myEnums;
                                      Q_ENUM(MyEnums)
                                      int m_myInt = 55;
                                      MyStruct() {}
                                  };
                                  

                                  This attempt doesn't work:

                                  Label { text: "myStruct.Enum3: " + myStruct.Enum3 }
                                  

                                  (it doesn't work with "MyStruct" either.)

                                  Can this be made to work? Thanks...

                                  EDIT 2:

                                  I have a workaround, which is to define my enums in a separate class and expose them to QML using the guidelines here, but if possible I'd prefer to avoid this level of indirection, and keep the enums in the struct.

                                  G Offline
                                  G Offline
                                  GrecKo
                                  Qt Champions 2018
                                  wrote on 11 Oct 2023, 07:55 last edited by
                                  #23

                                  @mzimmers I don't believe it is possible no. Instead of defining your enums in a separate class I would do it in a namespace with Q_ENUM_NS instead.

                                  G M 2 Replies Last reply 11 Oct 2023, 13:45
                                  0
                                  • G GrecKo
                                    10 Oct 2023, 14:45

                                    You can now instantiate Gadgets from QML with undocumented macros (so maybe don't use it).

                                    Use QML_VALUE_TYPE(typeName) with a lower case name like you currently do.
                                    Then you can add QML_CONSTRUCTIBLE_VALUE or QML_STRUCTURED_VALUE (even both).

                                    QML_CONSTRUCTIBLE_VALUE will call a user defined constructor

                                    if you have Q_INVOKABLE MyStruct(int foo) : m_myInt{foo} {}
                                    then doing property myStruct myStruct1: 42 will call the constructor with 42 as the foo param

                                    QML_STRUCTURED_VALUE will assign properties depending on the js object you passed in QML.

                                    property myStruct myStruct1: ({myInt: 42}) will create a default constructed MyStruct and assign its myInt property to 42.

                                    Note that the type should always be default constructible.

                                    EDIT: Note that you don't have to use QML_ELEMENT, Q_DECLARE_METATYPE or qmlRegisterType if you use Q_GADGET and QML_VALUE_TYPE.

                                    L Offline
                                    L Offline
                                    lemons
                                    wrote on 11 Oct 2023, 13:18 last edited by lemons 10 Nov 2023, 13:19
                                    #24

                                    @GrecKo said in using C++ classes and structs in QML:

                                    You can now instantiate Gadgets from QML with undocumented macros (so maybe don't use it).

                                    Use QML_VALUE_TYPE(typeName) with a lower case name like you currently do.
                                    Then you can add QML_CONSTRUCTIBLE_VALUE or QML_STRUCTURED_VALUE (even both).

                                    QML_CONSTRUCTIBLE_VALUE will call a user defined constructor

                                    if you have Q_INVOKABLE MyStruct(int foo) : m_myInt{foo} {}
                                    then doing property myStruct myStruct1: 42 will call the constructor with 42 as the foo param

                                    QML_STRUCTURED_VALUE will assign properties depending on the js object you passed in QML.

                                    property myStruct myStruct1: ({myInt: 42}) will create a default constructed MyStruct and assign its myInt property to 42.

                                    Note that the type should always be default constructible.

                                    EDIT: Note that you don't have to use QML_ELEMENT, Q_DECLARE_METATYPE or qmlRegisterType if you use Q_GADGET and QML_VALUE_TYPE.

                                    This is amazing !!
                                    Gonna have to explore the possibilities...

                                    1 Reply Last reply
                                    0
                                    • G GrecKo
                                      11 Oct 2023, 07:55

                                      @mzimmers I don't believe it is possible no. Instead of defining your enums in a separate class I would do it in a namespace with Q_ENUM_NS instead.

                                      G Offline
                                      G Offline
                                      GrecKo
                                      Qt Champions 2018
                                      wrote on 11 Oct 2023, 13:45 last edited by
                                      #25

                                      Coming back on what I said:

                                      It is possible to expose an enum from a Q_GADGET.

                                      If you add pragma ValueTypeBehavior: Addressable at the top of your QML file you can use the lower case gadget type name in QML and then do property int enumValue: myStruct.TestEnum.D

                                      Alternatively you could do it very verbosely with QML_FOREIGN_NAMESPACE like explained here : https://codereview.qt-project.org/c/qt/qtdeclarative/+/510832 (fresh out of the oven)

                                      1 Reply Last reply
                                      0
                                      • G GrecKo
                                        11 Oct 2023, 07:55

                                        @mzimmers I don't believe it is possible no. Instead of defining your enums in a separate class I would do it in a namespace with Q_ENUM_NS instead.

                                        M Offline
                                        M Offline
                                        mzimmers
                                        wrote on 11 Oct 2023, 16:22 last edited by
                                        #26

                                        @GrecKo said in using C++ classes and structs in QML:

                                        Instead of defining your enums in a separate class I would do it in a namespace with Q_ENUM_NS instead.

                                        namespace scheduleNS {
                                        Q_NAMESPACE
                                        enum StartAction {
                                            START_ACTION_TURN_ON,
                                            START_ACTION_TURN_OFF,
                                            START_ACTION_BE_READY,
                                            START_ACTION_SUSPEND
                                        };
                                        Q_ENUM_NS(StartAction)
                                        } // namespace
                                        

                                        but "scheduleNS" isn't recognized in my QML. How do I export a C++ namespace to QML?

                                        M kshegunovK G 3 Replies Last reply 12 Oct 2023, 15:39
                                        0
                                        • M mzimmers
                                          11 Oct 2023, 16:22

                                          @GrecKo said in using C++ classes and structs in QML:

                                          Instead of defining your enums in a separate class I would do it in a namespace with Q_ENUM_NS instead.

                                          namespace scheduleNS {
                                          Q_NAMESPACE
                                          enum StartAction {
                                              START_ACTION_TURN_ON,
                                              START_ACTION_TURN_OFF,
                                              START_ACTION_BE_READY,
                                              START_ACTION_SUSPEND
                                          };
                                          Q_ENUM_NS(StartAction)
                                          } // namespace
                                          

                                          but "scheduleNS" isn't recognized in my QML. How do I export a C++ namespace to QML?

                                          M Offline
                                          M Offline
                                          mzimmers
                                          wrote on 12 Oct 2023, 15:39 last edited by
                                          #27

                                          @mzimmers said in using C++ classes and structs in QML:

                                          How do I export a C++ namespace to QML?

                                          I should have asked, is there a newer alternative to the old method of manually registering it like this:

                                             qmlRegisterUncreatableMetaObject(scheduleNS::staticMetaObject, // static meta object
                                                                              "schedule.enums",          // import statement
                                                                              1, 0,                         // major and minor version of the import
                                                                              "ScheduleNS",                 // name in QML
                                                                              "Error: only enums");          // error in case someone tries to create a MyNamespace object
                                          

                                          This works fine, but given that we no longer need to use qmlRegisterType(), I was wondering whether there was a more modern way of doing the qmlRegisterUncreatableMetaObject() call.

                                          1 Reply Last reply
                                          0

                                          17/30

                                          10 Oct 2023, 14:22

                                          • Login

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