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. QML and Qt Quick
QtWS25 Last Chance

QML and Qt Quick

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 6 Posters 811 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.
  • H Offline
    H Offline
    hnar
    wrote on 10 Sept 2024, 07:40 last edited by
    #1

    Hello Everyone,
    I have a clarification question about context properties and their usage.

    Defining a context property in C++ and assigning it to a QML property, such as
    // c++
    QQmlApplicationEngine engine;
    MyCppClass myObject;
    engine.rootContext()->setContextProperty("myObject", &myObject);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    // qml
    Rectangle {
    width: 100
    height: 100
    property QtObject m_myObject: myObject
    Text {
    text: m_myObject.someProperty
    }
    }

    By assigning the context property (myObject) to a QML property (m_myObject), we create a duplicate reference to the same object in QML. This doesn’t duplicate the object itself but creates another reference to it. It can be helpful if this reference is used to simplify access or create a more readable QML structure.
    However, if the duplicate property doesn't add value, I believe it introduces unnecessary overhead. What is the best practice for this scenario? What issues can we face by having similar code across whole source files? Can we have performance issues because of this?

    G 1 Reply Last reply 10 Sept 2024, 09:42
    0
    • A Offline
      A Offline
      Axel Spoerl
      Moderators
      wrote on 10 Sept 2024, 07:52 last edited by
      #2

      Please edit this post and format the code using the </> code tags.
      Think about the time of those offering support in their free time: Nobody wants to decipher unformatted code.

      Software Engineer
      The Qt Company, Oslo

      1 Reply Last reply
      0
      • H hnar
        10 Sept 2024, 07:40

        Hello Everyone,
        I have a clarification question about context properties and their usage.

        Defining a context property in C++ and assigning it to a QML property, such as
        // c++
        QQmlApplicationEngine engine;
        MyCppClass myObject;
        engine.rootContext()->setContextProperty("myObject", &myObject);
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

        // qml
        Rectangle {
        width: 100
        height: 100
        property QtObject m_myObject: myObject
        Text {
        text: m_myObject.someProperty
        }
        }

        By assigning the context property (myObject) to a QML property (m_myObject), we create a duplicate reference to the same object in QML. This doesn’t duplicate the object itself but creates another reference to it. It can be helpful if this reference is used to simplify access or create a more readable QML structure.
        However, if the duplicate property doesn't add value, I believe it introduces unnecessary overhead. What is the best practice for this scenario? What issues can we face by having similar code across whole source files? Can we have performance issues because of this?

        G Offline
        G Offline
        GrecKo
        Qt Champions 2018
        wrote on 10 Sept 2024, 09:42 last edited by
        #3

        @hnar The best practice is not using context properties https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html

        B 1 Reply Last reply 10 Sept 2024, 13:31
        0
        • G GrecKo
          10 Sept 2024, 09:42

          @hnar The best practice is not using context properties https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html

          B Offline
          B Offline
          Bob64
          wrote on 10 Sept 2024, 13:31 last edited by
          #4

          @GrecKo said in QML and Qt Quick:

          @hnar The best practice is not using context properties https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html

          Hmm, I started switching to use qmlRegisterSingletonInstance recently in accordance with some previous advice on this forum. It now seems like that is being somewhat deprecated too.

          J 1 Reply Last reply 10 Sept 2024, 13:48
          0
          • B Bob64
            10 Sept 2024, 13:31

            @GrecKo said in QML and Qt Quick:

            @hnar The best practice is not using context properties https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html

            Hmm, I started switching to use qmlRegisterSingletonInstance recently in accordance with some previous advice on this forum. It now seems like that is being somewhat deprecated too.

            J Offline
            J Offline
            JKSH
            Moderators
            wrote on 10 Sept 2024, 13:48 last edited by
            #5

            @Bob64 said in QML and Qt Quick:

            @GrecKo said in QML and Qt Quick:

            @hnar The best practice is not using context properties https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html

            Hmm, I started switching to use qmlRegisterSingletonInstance recently in accordance with some previous advice on this forum. It now seems like that is being somewhat deprecated too.

            Indeed, QML_ELEMENT + QML_SINGLETON is the way to go

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            B 1 Reply Last reply 10 Sept 2024, 14:09
            0
            • J JKSH
              10 Sept 2024, 13:48

              @Bob64 said in QML and Qt Quick:

              @GrecKo said in QML and Qt Quick:

              @hnar The best practice is not using context properties https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html

              Hmm, I started switching to use qmlRegisterSingletonInstance recently in accordance with some previous advice on this forum. It now seems like that is being somewhat deprecated too.

              Indeed, QML_ELEMENT + QML_SINGLETON is the way to go

              B Offline
              B Offline
              Bob64
              wrote on 10 Sept 2024, 14:09 last edited by
              #6

              @JKSH said in QML and Qt Quick:

              Indeed, QML_ELEMENT + QML_SINGLETON is the way to go

              Yes, but I think QML_FOREIGN is also needed, and it's QML_NAMED_ELEMENT rather than QML_ELEMENT from what I understand from the 6.7 doc that was linked. I am still on 5.15 and this stuff is not yet documented there in the same way.

              To be clear, the use case being addressed is the ability to register an already constructed object as a QML singleton, rather than it actually being a C++ singleton. This is important if one wants to manage dependencies on the C++ side. In my experience, it is rare that an API class being exposed to QML has a completely standalone implementation that has no dependencies on external classes, and I want to control how those dependencies are passed in at construction rather than having to introduce a cascade of singletons.

              J 1 Reply Last reply 11 Sept 2024, 02:16
              0
              • E Offline
                E Offline
                ekkescorner
                Qt Champions 2016
                wrote on 10 Sept 2024, 15:28 last edited by
                #7

                here's how I did it with 6.7. (with some help of @GrecKo)
                https://t1p.de/ekkeQML_SINGLETON

                ekke ... Qt Champion 2016 | 2024 ... mobile business apps
                5.15 --> 6.8 https://t1p.de/ekkeChecklist
                QMake --> CMake https://t1p.de/ekkeCMakeMobileApps

                1 Reply Last reply
                3
                • B Offline
                  B Offline
                  Bob64
                  wrote on 10 Sept 2024, 16:50 last edited by
                  #8

                  @ekkescorner Thank you! I have bookmarked your site - it looks like you have a lot of useful information there!

                  1 Reply Last reply
                  0
                  • B Bob64
                    10 Sept 2024, 14:09

                    @JKSH said in QML and Qt Quick:

                    Indeed, QML_ELEMENT + QML_SINGLETON is the way to go

                    Yes, but I think QML_FOREIGN is also needed, and it's QML_NAMED_ELEMENT rather than QML_ELEMENT from what I understand from the 6.7 doc that was linked. I am still on 5.15 and this stuff is not yet documented there in the same way.

                    To be clear, the use case being addressed is the ability to register an already constructed object as a QML singleton, rather than it actually being a C++ singleton. This is important if one wants to manage dependencies on the C++ side. In my experience, it is rare that an API class being exposed to QML has a completely standalone implementation that has no dependencies on external classes, and I want to control how those dependencies are passed in at construction rather than having to introduce a cascade of singletons.

                    J Offline
                    J Offline
                    JKSH
                    Moderators
                    wrote on 11 Sept 2024, 02:16 last edited by
                    #9

                    @Bob64 said in QML and Qt Quick:

                    Yes, but I think QML_FOREIGN is also needed, and it's QML_NAMED_ELEMENT rather than QML_ELEMENT from what I understand from the 6.7 doc that was linked. I am still on 5.15 and this stuff is not yet documented there in the same way.

                    • QML_ELEMENT uses the C++ class name as the QML type name
                    • QML_NAMED_ELEMENT() ignores the C++ class name and lets you specify a different name for the QML type

                    Aside from this difference, these 2 macros do the same thing.

                    QML_FOREIGN is only needed for cases where your original class doesn't have QML_ELEMENT/QML_NAMED_ELEMENT() (for example, if the original class is from a 3rd-party library that you don't control). You would then need to create a dummy/wrapper/boilerplate class to expose the original (foreign) class to QML.

                    To be clear, the use case being addressed is the ability to register an already constructed object as a QML singleton, rather than it actually being a C++ singleton. This is important if one wants to manage dependencies on the C++ side. In my experience, it is rare that an API class being exposed to QML has a completely standalone implementation that has no dependencies on external classes, and I want to control how those dependencies are passed in at construction rather than having to introduce a cascade of singletons.

                    You can certainly do this via QML_ELEMENT/QML_NAMED_ELEMENT() + QML_SINGLETON:

                    1. Construct your instance before loading your QML code
                    2. Store your desired instance in a global/static variable, myInstance
                    3. Implement a static method with this signature: static MyClass* MyClass::create(QQmlEngine*, QJSEngine*) -- this method should call QJSEngine::setObjectOwnership(myInstance, QJSEngine::CppOwnership); and then return myInstance`
                    4. Load your QML code

                    When the QML engine loads your module, it will call MyClass::create() and use the returned pointer as the singleton object.

                    See the MyNonDefaultConstructibleSingleton example at https://doc.qt.io/qt-6/qml-singleton.html#registering-a-class-to-provide-singletons

                    Addendum: "Why go through all this trouble?"
                    In case you're wondering, the qmlRegister*() functions perform registration at runtime, while QML_ELEMENT and friends perform registration at compile-time. Compile-time registration enables the Qt Quick Compiler to optimize your code: https://www.qt.io/blog/qt-6.6-and-6.7-make-qml-faster-than-ever-a-new-benchmark-and-analysis

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    G 1 Reply Last reply 11 Sept 2024, 07:25
                    0
                    • J JKSH
                      11 Sept 2024, 02:16

                      @Bob64 said in QML and Qt Quick:

                      Yes, but I think QML_FOREIGN is also needed, and it's QML_NAMED_ELEMENT rather than QML_ELEMENT from what I understand from the 6.7 doc that was linked. I am still on 5.15 and this stuff is not yet documented there in the same way.

                      • QML_ELEMENT uses the C++ class name as the QML type name
                      • QML_NAMED_ELEMENT() ignores the C++ class name and lets you specify a different name for the QML type

                      Aside from this difference, these 2 macros do the same thing.

                      QML_FOREIGN is only needed for cases where your original class doesn't have QML_ELEMENT/QML_NAMED_ELEMENT() (for example, if the original class is from a 3rd-party library that you don't control). You would then need to create a dummy/wrapper/boilerplate class to expose the original (foreign) class to QML.

                      To be clear, the use case being addressed is the ability to register an already constructed object as a QML singleton, rather than it actually being a C++ singleton. This is important if one wants to manage dependencies on the C++ side. In my experience, it is rare that an API class being exposed to QML has a completely standalone implementation that has no dependencies on external classes, and I want to control how those dependencies are passed in at construction rather than having to introduce a cascade of singletons.

                      You can certainly do this via QML_ELEMENT/QML_NAMED_ELEMENT() + QML_SINGLETON:

                      1. Construct your instance before loading your QML code
                      2. Store your desired instance in a global/static variable, myInstance
                      3. Implement a static method with this signature: static MyClass* MyClass::create(QQmlEngine*, QJSEngine*) -- this method should call QJSEngine::setObjectOwnership(myInstance, QJSEngine::CppOwnership); and then return myInstance`
                      4. Load your QML code

                      When the QML engine loads your module, it will call MyClass::create() and use the returned pointer as the singleton object.

                      See the MyNonDefaultConstructibleSingleton example at https://doc.qt.io/qt-6/qml-singleton.html#registering-a-class-to-provide-singletons

                      Addendum: "Why go through all this trouble?"
                      In case you're wondering, the qmlRegister*() functions perform registration at runtime, while QML_ELEMENT and friends perform registration at compile-time. Compile-time registration enables the Qt Quick Compiler to optimize your code: https://www.qt.io/blog/qt-6.6-and-6.7-make-qml-faster-than-ever-a-new-benchmark-and-analysis

                      G Offline
                      G Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on 11 Sept 2024, 07:25 last edited by GrecKo 9 Nov 2024, 07:29
                      #10

                      @JKSH said in QML and Qt Quick:

                      You can certainly do this via QML_ELEMENT/QML_NAMED_ELEMENT() + QML_SINGLETON:

                      • Construct your instance before loading your QML code
                      • Store your desired instance in a global/static variable, myInstance
                      • Implement a static method with this signature: static MyClass* MyClass::create(QQmlEngine*, QJSEngine*) -- this method should call QJSEngine::setObjectOwnership(myInstance, QJSEngine::CppOwnership); and then return myInstance`
                      • Load your QML code

                      This also requires that MyClass is not defaut constructible (= has no constructor without parameter or with only default parameter).
                      This doesn't work if there is a MyClass() constructor or MyClass(QObject* parent = nullptr). This is an infortunate requirement and that's why using another QML_FOREIGN class to declare the singleton is sometime recommended.

                      1 Reply Last reply
                      2
                      • H Offline
                        H Offline
                        hnar
                        wrote on 12 Sept 2024, 06:23 last edited by
                        #11

                        Thank you so much, everyone! I appreciate all your responses. Unfortunately, I was not able to edit my post. The system did not allow me.

                        1 Reply Last reply
                        0
                        • B Bob64 referenced this topic on 21 Nov 2024, 08:33
                        • B Bob64 referenced this topic on 29 Mar 2025, 11:51

                        5/11

                        10 Sept 2024, 13:48

                        • Login

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