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
Forum Updated to NodeBB v4.3 + New Features

QML and Qt Quick

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 6 Posters 1.1k Views 4 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.
  • 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 Offline
      GrecKoG Offline
      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 Online
          JKSHJ Online
          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.9 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 Online
                  JKSHJ Online
                  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 Offline
                    GrecKoG Offline
                    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