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. QtObject instantiated by QML and it's parent
Forum Updated to NodeBB v4.3 + New Features

QtObject instantiated by QML and it's parent

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
15 Posts 4 Posters 2.5k Views 2 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.
  • DuBuD Offline
    DuBuD Offline
    DuBu
    wrote on last edited by
    #1

    Hi,

    when I have a custom component written in C++ and instantiated in QML, it's constructor is called with parent = nullptr. But later on the parent was set somehow. Is there any signal I can connect to, telling me the parent has been set?

    Regards,
    Stephan

    KroMignonK 1 Reply Last reply
    0
    • DuBuD DuBu

      Hi,

      when I have a custom component written in C++ and instantiated in QML, it's constructor is called with parent = nullptr. But later on the parent was set somehow. Is there any signal I can connect to, telling me the parent has been set?

      Regards,
      Stephan

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by KroMignon
      #2

      @DuBu said in QtObject instantiated by QML and it's parent:

      when I have a custom component written in C++ and instantiated in QML, it's constructor is called with parent = nullptr. But later on the parent was set somehow. Is there any signal I can connect to, telling me the parent has been set?

      Per default, the QML engine take ownership over QObject which don't have a parent (cf https://doc.qt.io/qt-5/qtqml-cppintegration-data.html).

      AFAIK, there is no signal emitted on parent changes.

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      1 Reply Last reply
      1
      • DuBuD Offline
        DuBuD Offline
        DuBu
        wrote on last edited by
        #3

        So it seems I could reimplement "bool Object::event(QEvent *)" and check for QEvent::ParentChange.
        Unfortunately there's no QEvent::ParentChange and QEvent::ParentAboutToChange, although the parent changes.

        jeremy_kJ 1 Reply Last reply
        0
        • DuBuD DuBu

          So it seems I could reimplement "bool Object::event(QEvent *)" and check for QEvent::ParentChange.
          Unfortunately there's no QEvent::ParentChange and QEvent::ParentAboutToChange, although the parent changes.

          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by
          #4

          @DuBu said in QtObject instantiated by QML and it's parent:

          So it seems I could reimplement "bool Object::event(QEvent *)" and check for QEvent::ParentChange.
          Unfortunately there's no QEvent::ParentChange and QEvent::ParentAboutToChange, although the parent changes.

          These events only apply to QWidget derived objects.

          QEvent::ChildAdded is generated for QObject parent changes, although it's sent to the parent rather than the child.

          QQuickItem has a parentChanged signal.

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          0
          • GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            Can you describe us your usecase a bit more @DuBu to figure out if there's a possible alternative?

            DuBuD 1 Reply Last reply
            0
            • GrecKoG GrecKo

              Can you describe us your usecase a bit more @DuBu to figure out if there's a possible alternative?

              DuBuD Offline
              DuBuD Offline
              DuBu
              wrote on last edited by
              #6

              @GrecKo The component need to access it's parent component to do it's job. But I don't know how to access the parent when the "parent" argument of the constructor is NULL and there's no signal the component could catch when the parent actually has been set. I could use a timer, but that's not way i think it should work.

              KroMignonK 1 Reply Last reply
              0
              • DuBuD DuBu

                @GrecKo The component need to access it's parent component to do it's job. But I don't know how to access the parent when the "parent" argument of the constructor is NULL and there's no signal the component could catch when the parent actually has been set. I could use a timer, but that's not way i think it should work.

                KroMignonK Offline
                KroMignonK Offline
                KroMignon
                wrote on last edited by KroMignon
                #7

                @DuBu said in QtObject instantiated by QML and it's parent:

                The component need to access it's parent component to do it's job. But I don't know how to access the parent when the "parent" argument of the constructor is NULL and there's no signal the component could catch when the parent actually has been set. I could use a timer, but that's not way i think it should work.

                If I am remember right your use case: on create QObject based classes which are used from QML.
                And you want to execute "something" when the instance is initialized by the QML engine.
                My suggestion would be to use Component.onCompleted to do that.
                Supposing your class is called MyItem:

                MyItem {
                    Component.onCompleted: {
                         // do stuff here
                    }
                }
                

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                DuBuD 1 Reply Last reply
                0
                • KroMignonK KroMignon

                  @DuBu said in QtObject instantiated by QML and it's parent:

                  The component need to access it's parent component to do it's job. But I don't know how to access the parent when the "parent" argument of the constructor is NULL and there's no signal the component could catch when the parent actually has been set. I could use a timer, but that's not way i think it should work.

                  If I am remember right your use case: on create QObject based classes which are used from QML.
                  And you want to execute "something" when the instance is initialized by the QML engine.
                  My suggestion would be to use Component.onCompleted to do that.
                  Supposing your class is called MyItem:

                  MyItem {
                      Component.onCompleted: {
                           // do stuff here
                      }
                  }
                  
                  DuBuD Offline
                  DuBuD Offline
                  DuBu
                  wrote on last edited by
                  #8

                  @KroMignon I want to do it in c++ and I want to preferably access the parent before any property got set/bound.

                  KroMignonK 1 Reply Last reply
                  0
                  • DuBuD DuBu

                    @KroMignon I want to do it in c++ and I want to preferably access the parent before any property got set/bound.

                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by KroMignon
                    #9

                    @DuBu said in QtObject instantiated by QML and it's parent:

                    I want to do it in c++ and I want to preferably access the parent before any property got set/bound.

                    Sound complicated to me, AFAIK the instance will send an QEvent::ChildAdded / QEvent::ChildRemoved event on parent changes but only to the new/previous parent instance.

                    I think, you have to redesign your application.

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    1 Reply Last reply
                    0
                    • DuBuD Offline
                      DuBuD Offline
                      DuBu
                      wrote on last edited by
                      #10

                      Here's my use case:

                      ParentQObjectComp {
                        MyInstantiator {
                          ChildQObjectComp {}
                        }
                      }
                      

                      So all 3 components are written in c++ and derived from QObject. Now in MyInstantiator I want to add the ChildQObjectComp to the ParentQObjectComp which is the parent of MyInstantiator. The only way I can think of is to access the parent in the moment the ChildQObjectComp get's added to MyInstantiator.

                      KroMignonK 1 Reply Last reply
                      0
                      • DuBuD DuBu

                        Here's my use case:

                        ParentQObjectComp {
                          MyInstantiator {
                            ChildQObjectComp {}
                          }
                        }
                        

                        So all 3 components are written in c++ and derived from QObject. Now in MyInstantiator I want to add the ChildQObjectComp to the ParentQObjectComp which is the parent of MyInstantiator. The only way I can think of is to access the parent in the moment the ChildQObjectComp get's added to MyInstantiator.

                        KroMignonK Offline
                        KroMignonK Offline
                        KroMignon
                        wrote on last edited by
                        #11

                        @DuBu said in QtObject instantiated by QML and it's parent:

                        So all 3 components are written in c++ and derived from QObject. Now in MyInstantiator I want to add the ChildQObjectComp to the ParentQObjectComp which is the parent of MyInstantiator. The only way I can think of is to access the parent in the moment the ChildQObjectComp get's added to MyInstantiator.

                        I am pretty sure that MyInstantiator instance will receive an QEvent::ChildAdded event from ChildQObjectComp.
                        And ParentQObjectComp instance same event from MyInstantiator instance
                        Is that not enough for you?

                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                        DuBuD 1 Reply Last reply
                        0
                        • KroMignonK KroMignon

                          @DuBu said in QtObject instantiated by QML and it's parent:

                          So all 3 components are written in c++ and derived from QObject. Now in MyInstantiator I want to add the ChildQObjectComp to the ParentQObjectComp which is the parent of MyInstantiator. The only way I can think of is to access the parent in the moment the ChildQObjectComp get's added to MyInstantiator.

                          I am pretty sure that MyInstantiator instance will receive an QEvent::ChildAdded event from ChildQObjectComp.
                          And ParentQObjectComp instance same event from MyInstantiator instance
                          Is that not enough for you?

                          DuBuD Offline
                          DuBuD Offline
                          DuBu
                          wrote on last edited by
                          #12

                          @KroMignon When MyInstantiator receives the ChildAdded event for ChildQObjectComp it need's to access it's parent. But MyInstantiator doesn't know it's parent cause there's no ParentChange event. The ChildAdded event in ParentQObjectComp for MyInstantiator is not useful cause it doesn't know anything about a MyInstantiator and therefor it doesn't know what to do with the event.

                          KroMignonK 1 Reply Last reply
                          0
                          • DuBuD DuBu

                            @KroMignon When MyInstantiator receives the ChildAdded event for ChildQObjectComp it need's to access it's parent. But MyInstantiator doesn't know it's parent cause there's no ParentChange event. The ChildAdded event in ParentQObjectComp for MyInstantiator is not useful cause it doesn't know anything about a MyInstantiator and therefor it doesn't know what to do with the event.

                            KroMignonK Offline
                            KroMignonK Offline
                            KroMignon
                            wrote on last edited by KroMignon
                            #13

                            @DuBu said in QtObject instantiated by QML and it's parent:

                            When MyInstantiator receives the ChildAdded event for ChildQObjectComp it need's to access it's parent. But MyInstantiator doesn't know it's parent cause there's no ParentChange event. The ChildAdded event in ParentQObjectComp for MyInstantiator is not useful cause it doesn't know anything about a MyInstantiator and therefor it doesn't know what to do with the event.

                            Again, as I wrote before, you have to redesign your code. It is not possible to handle this in C++ directly.
                            You could perhaps use eventFilter and "catch" all QEvent::ChildAdded and check if the receiver is an MyInstantiator:

                            class ParentFilter : public QObject
                            {
                                Q_OBJECT
                            
                            public:
                                explicit ParentFilter (QObject *parent = 0): QObject(parent) {}
                            
                            public:
                                bool eventFilter(QObject *object, QEvent *event)
                                {
                                    if (event->type() == QEvent::ChildAdded ) 
                                    {
                                         QChildEvent*childEvent = static_cast<QChildEvent*>(event);
                                         MyInstantiator* o = qobject_cast<MyInstantiator*>(childEvent->child());
                                         if(o)
                                         {
                                             // do stuff here
                                         }
                                    }
                                    return QObject::eventFilter(object,event);
                                }
                            };
                            

                            Then register the filter:

                            qApp->installEventFilter(new ParentFilter(qApp));
                            

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            DuBuD 1 Reply Last reply
                            0
                            • KroMignonK KroMignon

                              @DuBu said in QtObject instantiated by QML and it's parent:

                              When MyInstantiator receives the ChildAdded event for ChildQObjectComp it need's to access it's parent. But MyInstantiator doesn't know it's parent cause there's no ParentChange event. The ChildAdded event in ParentQObjectComp for MyInstantiator is not useful cause it doesn't know anything about a MyInstantiator and therefor it doesn't know what to do with the event.

                              Again, as I wrote before, you have to redesign your code. It is not possible to handle this in C++ directly.
                              You could perhaps use eventFilter and "catch" all QEvent::ChildAdded and check if the receiver is an MyInstantiator:

                              class ParentFilter : public QObject
                              {
                                  Q_OBJECT
                              
                              public:
                                  explicit ParentFilter (QObject *parent = 0): QObject(parent) {}
                              
                              public:
                                  bool eventFilter(QObject *object, QEvent *event)
                                  {
                                      if (event->type() == QEvent::ChildAdded ) 
                                      {
                                           QChildEvent*childEvent = static_cast<QChildEvent*>(event);
                                           MyInstantiator* o = qobject_cast<MyInstantiator*>(childEvent->child());
                                           if(o)
                                           {
                                               // do stuff here
                                           }
                                      }
                                      return QObject::eventFilter(object,event);
                                  }
                              };
                              

                              Then register the filter:

                              qApp->installEventFilter(new ParentFilter(qApp));
                              
                              DuBuD Offline
                              DuBuD Offline
                              DuBu
                              wrote on last edited by
                              #14

                              @KroMignon That's a nice approach. Thanks for the code!
                              I recon in my special use case it's sufficient to access the parent in the event handler for ChildAdded in MyInstantiator, which is hopefully already set at that time.
                              Thanks for the hints to ChildAdded/ChildRemoved events.

                              1 Reply Last reply
                              0
                              • GrecKoG Offline
                                GrecKoG Offline
                                GrecKo
                                Qt Champions 2018
                                wrote on last edited by GrecKo
                                #15

                                What about overriding QQmlParserStatus::classBegin and using QObject::parent() to retrieve the parent?
                                Another way to do it would just be to add a property in MyInstantiator to specify the ParentQObjectComp, the advantage is that you can define an Instantiator outside of the QML hierarchy of ParentQObjectComp.

                                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