Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to manage QObject instance which is shared among lots of C++/QML places

How to manage QObject instance which is shared among lots of C++/QML places

Scheduled Pinned Locked Moved QML and Qt Quick
13 Posts 3 Posters 4.6k 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.
  • X xylosper

    Suppose I have an QObject-derived instance.

    If I have to share this instance in C++, I'll use QSharedPointer or std::shared_ptr.
    If I have to share this instance in QML, I'll set the ownership to JavascriptOwnership and let the QML engine manage it.

    However, now I have to share this instance in both of C++ and QML.
    I cannot set JavascriptOwnership because this instance should be alive while used in C++.
    I cannot use QSharedPointer because once I expose raw pointer encapsualted in QSharedPointer to QML, reference-counting makes no more sense.

    How should I manage such instance?

    kshegunovK Offline
    kshegunovK Offline
    kshegunov
    Moderators
    wrote on last edited by kshegunov
    #3

    @xylosper said in How to manage QObject instance which is shared among lots of C++/QML places:

    If I have to share this instance in C++, I'll use QSharedPointer or std::shared_ptr.

    You shouldn't do that even from C++. A shared pointer holds an instance to an object that manages its own lifetime and QObjects don't! Their lifetime is either managed by their parent or manually by you. You should either use QScopedPointer or QPointer depending on the situation.

    As a side note you can't use implicit sharing with QObjects as @raven-worx suggested. That'd be no different than holding it in QSharedPointer

    If you need it to persist throughout I'd parent it to the application object and register it as a global object for QML before the engine starts up. However you should elaborate on the lifetime of said object, when should it be created and when should it be destroyed?

    Read and abide by the Qt Code of Conduct

    1 Reply Last reply
    0
    • raven-worxR raven-worx

      @xylosper
      you could use the same approach like Qt's implicit sharing.
      The wrapper class can be created multiple times. Each wrapper class holds an shared pointer to the actual data. (make sure you implement the copy constructor and assignment operator).

      X Offline
      X Offline
      xylosper
      wrote on last edited by
      #4

      @raven-worx

      If I write a wrapper class. doesn't it mean that I have to write duplicated slots/signals?

      @kshegunov

      You shouldn't do that even from C++. A shared pointer holds an instance to an object that manages its own lifetime and QObjects don't! Their lifetime is either managed by their parent or manually by you. You should either use QScopedPointer or QPointer depending on the situation.

      Why not? It's just a pointer to an object. All my instances does not have a parent.
      It's derived from QObject only for signal.
      Even if it has a parent, Qt will remove the child information automatically in child list of parent when the instance deleted at outside of parent's dtor. Or, may I miss something here..?

      If you need it to persist

      Nope, my instance is not permanent. It can be created in both of C++ and QML and also can be deleted in both of C++ and QML.
      Also, it is not a unique one. It cannot be a singletone.

      raven-worxR kshegunovK 2 Replies Last reply
      0
      • X xylosper

        @raven-worx

        If I write a wrapper class. doesn't it mean that I have to write duplicated slots/signals?

        @kshegunov

        You shouldn't do that even from C++. A shared pointer holds an instance to an object that manages its own lifetime and QObjects don't! Their lifetime is either managed by their parent or manually by you. You should either use QScopedPointer or QPointer depending on the situation.

        Why not? It's just a pointer to an object. All my instances does not have a parent.
        It's derived from QObject only for signal.
        Even if it has a parent, Qt will remove the child information automatically in child list of parent when the instance deleted at outside of parent's dtor. Or, may I miss something here..?

        If you need it to persist

        Nope, my instance is not permanent. It can be created in both of C++ and QML and also can be deleted in both of C++ and QML.
        Also, it is not a unique one. It cannot be a singletone.

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #5

        @xylosper said in How to manage QObject instance which is shared among lots of C++/QML places:

        If I write a wrapper class. doesn't it mean that I have to write duplicated slots/signals?

        Do the connection (signal forwarding) in the copy constructor and assignment operator. Since you anyway want to use it in QML you can use the automatic property binding (declare a Q_PROPERTY in the wrapper class).

        @kshegunov
        i also don't see where the problem is? Just by using a QObject instance doesnt mean that you have to put it an parent-child-relationship.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        0
        • X xylosper

          @raven-worx

          If I write a wrapper class. doesn't it mean that I have to write duplicated slots/signals?

          @kshegunov

          You shouldn't do that even from C++. A shared pointer holds an instance to an object that manages its own lifetime and QObjects don't! Their lifetime is either managed by their parent or manually by you. You should either use QScopedPointer or QPointer depending on the situation.

          Why not? It's just a pointer to an object. All my instances does not have a parent.
          It's derived from QObject only for signal.
          Even if it has a parent, Qt will remove the child information automatically in child list of parent when the instance deleted at outside of parent's dtor. Or, may I miss something here..?

          If you need it to persist

          Nope, my instance is not permanent. It can be created in both of C++ and QML and also can be deleted in both of C++ and QML.
          Also, it is not a unique one. It cannot be a singletone.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #6

          @xylosper, @raven-worx
          https://forum.qt.io/topic/74147/share-qstring-between-threads
          It includes links to the mailing list with more information. Basically the problem is you can't guarantee the time of destruction of the object (implying multithreading here), which in turn leads to the possibility of having a queued event that is handled by a deleted QObject. The result is a cryptic segfault in the event loop processing.

          Read and abide by the Qt Code of Conduct

          raven-worxR 1 Reply Last reply
          0
          • kshegunovK kshegunov

            @xylosper, @raven-worx
            https://forum.qt.io/topic/74147/share-qstring-between-threads
            It includes links to the mailing list with more information. Basically the problem is you can't guarantee the time of destruction of the object (implying multithreading here), which in turn leads to the possibility of having a queued event that is handled by a deleted QObject. The result is a cryptic segfault in the event loop processing.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #7

            @kshegunov
            yes, but where is the threading involved here?

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            kshegunovK 1 Reply Last reply
            0
            • raven-worxR raven-worx

              @kshegunov
              yes, but where is the threading involved here?

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #8

              @raven-worx said in How to manage QObject instance which is shared among lots of C++/QML places:

              @kshegunov
              yes, but where is the threading involved here?

              Doesn't QML employ threads internally? I might be wrong, but I thought it did.

              Read and abide by the Qt Code of Conduct

              raven-worxR 1 Reply Last reply
              0
              • kshegunovK kshegunov

                @raven-worx said in How to manage QObject instance which is shared among lots of C++/QML places:

                @kshegunov
                yes, but where is the threading involved here?

                Doesn't QML employ threads internally? I might be wrong, but I thought it did.

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by
                #9

                @kshegunov
                AFAIK it runs on the GUI thread

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                kshegunovK 1 Reply Last reply
                0
                • raven-worxR raven-worx

                  @kshegunov
                  AFAIK it runs on the GUI thread

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #10

                  @raven-worx
                  Fair enough. If that's the case, my comment can be disregarded.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  0
                  • X xylosper

                    Suppose I have an QObject-derived instance.

                    If I have to share this instance in C++, I'll use QSharedPointer or std::shared_ptr.
                    If I have to share this instance in QML, I'll set the ownership to JavascriptOwnership and let the QML engine manage it.

                    However, now I have to share this instance in both of C++ and QML.
                    I cannot set JavascriptOwnership because this instance should be alive while used in C++.
                    I cannot use QSharedPointer because once I expose raw pointer encapsualted in QSharedPointer to QML, reference-counting makes no more sense.

                    How should I manage such instance?

                    X Offline
                    X Offline
                    xylosper
                    wrote on last edited by
                    #11

                    @kshegunov

                    Doesn't QML employ threads internally? I might be wrong, but I thought it did.

                    Yes, generally, QML runs on both of main GUI thread and scene graph rendering thread.
                    But the rendering thread won't appear unless you're writing some custom rendering items.
                    Things unrelated with rendering, all QML codes run on GUI thread, and my object lives in GUI thread only.
                    FYI, please see Threaded Render Loop ("threaded") section from here http://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph.html
                    Thank you.

                    @raven-worx

                    Do the connection (signal forwarding) in the copy constructor and assignment operator. Since you anyway want to use it in QML you can use the automatic property binding (declare a Q_PROPERTY in the wrapper class).

                    Yes, I can do it. It makes me omit duplicated implementation but still, I need to copy the interfaces(signals/slots/Q_INVOKABLEs).
                    But it seems that that's the only workaround. Thank you.

                    raven-worxR 1 Reply Last reply
                    0
                    • X xylosper

                      @kshegunov

                      Doesn't QML employ threads internally? I might be wrong, but I thought it did.

                      Yes, generally, QML runs on both of main GUI thread and scene graph rendering thread.
                      But the rendering thread won't appear unless you're writing some custom rendering items.
                      Things unrelated with rendering, all QML codes run on GUI thread, and my object lives in GUI thread only.
                      FYI, please see Threaded Render Loop ("threaded") section from here http://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph.html
                      Thank you.

                      @raven-worx

                      Do the connection (signal forwarding) in the copy constructor and assignment operator. Since you anyway want to use it in QML you can use the automatic property binding (declare a Q_PROPERTY in the wrapper class).

                      Yes, I can do it. It makes me omit duplicated implementation but still, I need to copy the interfaces(signals/slots/Q_INVOKABLEs).
                      But it seems that that's the only workaround. Thank you.

                      raven-worxR Offline
                      raven-worxR Offline
                      raven-worx
                      Moderators
                      wrote on last edited by
                      #12

                      @xylosper
                      you could also try to register a singleton type.

                      In your case the static singleton provider would look like something this:

                      MySingleTonType* g_SingletonTypeInstance = 0; // global or static instance
                      
                      static QObject *example_qobject_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
                      {
                            if( g_SingletonTypeInstance == 0 )
                                 g_SingletonTypeInstance = new MySingleTonType;
                           return g_SingletonTypeInstance;
                      }
                      

                      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                      If you have a question please use the forum so others can benefit from the solution in the future

                      X 1 Reply Last reply
                      0
                      • raven-worxR raven-worx

                        @xylosper
                        you could also try to register a singleton type.

                        In your case the static singleton provider would look like something this:

                        MySingleTonType* g_SingletonTypeInstance = 0; // global or static instance
                        
                        static QObject *example_qobject_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
                        {
                              if( g_SingletonTypeInstance == 0 )
                                   g_SingletonTypeInstance = new MySingleTonType;
                             return g_SingletonTypeInstance;
                        }
                        
                        X Offline
                        X Offline
                        xylosper
                        wrote on last edited by
                        #13

                        @raven-worx

                        Unfortunately, singleton is my option. Although I said 'an' instance only for example, the class could be instantiated several times. Sorry for incorrect discription.

                        1 Reply Last reply
                        0

                        • Login

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