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 813 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 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?

    GrecKoG 1 Reply Last reply
    0
    • Axel SpoerlA Offline
      Axel SpoerlA Offline
      Axel Spoerl
      Moderators
      wrote on 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

        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?

        GrecKoG Online
        GrecKoG Online
        GrecKo
        Qt Champions 2018
        wrote on 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
        0
        • GrecKoG GrecKo

          @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 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.

          JKSHJ 1 Reply Last reply
          0
          • B Bob64

            @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.

            JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on 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
            0
            • JKSHJ JKSH

              @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 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.

              JKSHJ 1 Reply Last reply
              0
              • ekkescornerE Offline
                ekkescornerE Offline
                ekkescorner
                Qt Champions 2016
                wrote on 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 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

                    @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.

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on 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

                    GrecKoG 1 Reply Last reply
                    0
                    • JKSHJ JKSH

                      @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

                      GrecKoG Online
                      GrecKoG Online
                      GrecKo
                      Qt Champions 2018
                      wrote on last edited by GrecKo
                      #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 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
                        • B Bob64 referenced this topic on

                        • Login

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