Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Access parent from child class
QtWS25 Last Chance

Access parent from child class

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 706 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.
  • D Offline
    D Offline
    dalishi
    wrote on last edited by dalishi
    #1

    Hi, I have a Child class like this

    MyChild::MyChild(QObject *parent)
        : QObject{parent}
    {
    

    I want to call some parent's function from this Child class, I found calling from Child's constructor and Child's member funcion is different.

    1. Calling from Child's constructor:

    MyChild::MyChild(QObject *parent)
        : QObject{parent}
    {
        qobject_cast<MyParent *>(parent()); // ERROR: called object type 'QWidget *' is not a function or function pointer
    
    

    Fix:

    qobject_cast<MyParent *>(parent); // without (), I guess this is calling the passed param QObject *parent
    

    or:

    qobject_cast<MyParent *>(this->parent()); // using this->
    

    2. Calling from Child's member function:

     qobject_cast<MainVisualizer *>(parent()); // is OK
    

    My question is why I cannot directly call parent() in constructor?

    JonBJ 1 Reply Last reply
    0
    • D dalishi

      Hi, I have a Child class like this

      MyChild::MyChild(QObject *parent)
          : QObject{parent}
      {
      

      I want to call some parent's function from this Child class, I found calling from Child's constructor and Child's member funcion is different.

      1. Calling from Child's constructor:

      MyChild::MyChild(QObject *parent)
          : QObject{parent}
      {
          qobject_cast<MyParent *>(parent()); // ERROR: called object type 'QWidget *' is not a function or function pointer
      
      

      Fix:

      qobject_cast<MyParent *>(parent); // without (), I guess this is calling the passed param QObject *parent
      

      or:

      qobject_cast<MyParent *>(this->parent()); // using this->
      

      2. Calling from Child's member function:

       qobject_cast<MainVisualizer *>(parent()); // is OK
      

      My question is why I cannot directly call parent() in constructor?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @dalishi said in Access parent from child class:

      I want to call some parent's function from this Child class

      As a starting point, this is (usually at minimum) a really bad idea/architectural design. It tends towards breaking half the point of OOP. Why would you want to do this?

      I found calling from Child's constructor and Child's member funcion is different.

      I don't think so.

      qobject_cast<MyParent *>(parent()); // ERROR: called object type 'QWidget *' is not a function or function pointer

      The error is correct. What do you think parent() (same for any QObject *, or indeed any non-function-pointer) should do?

      qobject_cast<MyParent *>(parent); // without (), I guess this is calling the passed param QObject *parent

      This at least is "correct", but pointless as it stands. It does not call anything, that is important to understand. It (tries to) cast parent to a MyParent *, and then throws away the result, which is essentially a no-operation.

      qobject_cast<MainVisualizer *>(parent()); // is OK

      Because elsewhere than the constructor parent is a different thing.

      Let's go back. Your constructor is declared as

      MyChild::MyChild(QObject *parent)
      

      That makes parent a variable here, passed as a parameter. You cannot call parent() on that, it doesn't make sense.

      Quite separately, anything derived from QObject has a QObject *QObject::parent() const member method --- which actually returns the parent parameter originally passed to the constructor. this->parent() will call that. parent() on its own will call that within the class, unless there is variable named parent in scope, as in the constructor. So that's the answer for your confusion.

      Back to your original architecture: why are you wanting to cast the parent of your MyChild widget to see if it is a MainVisualizer? You really should not need to be doing this, there is likely to be a much better way of arranging things.

      D 1 Reply Last reply
      1
      • JonBJ JonB

        @dalishi said in Access parent from child class:

        I want to call some parent's function from this Child class

        As a starting point, this is (usually at minimum) a really bad idea/architectural design. It tends towards breaking half the point of OOP. Why would you want to do this?

        I found calling from Child's constructor and Child's member funcion is different.

        I don't think so.

        qobject_cast<MyParent *>(parent()); // ERROR: called object type 'QWidget *' is not a function or function pointer

        The error is correct. What do you think parent() (same for any QObject *, or indeed any non-function-pointer) should do?

        qobject_cast<MyParent *>(parent); // without (), I guess this is calling the passed param QObject *parent

        This at least is "correct", but pointless as it stands. It does not call anything, that is important to understand. It (tries to) cast parent to a MyParent *, and then throws away the result, which is essentially a no-operation.

        qobject_cast<MainVisualizer *>(parent()); // is OK

        Because elsewhere than the constructor parent is a different thing.

        Let's go back. Your constructor is declared as

        MyChild::MyChild(QObject *parent)
        

        That makes parent a variable here, passed as a parameter. You cannot call parent() on that, it doesn't make sense.

        Quite separately, anything derived from QObject has a QObject *QObject::parent() const member method --- which actually returns the parent parameter originally passed to the constructor. this->parent() will call that. parent() on its own will call that within the class, unless there is variable named parent in scope, as in the constructor. So that's the answer for your confusion.

        Back to your original architecture: why are you wanting to cast the parent of your MyChild widget to see if it is a MainVisualizer? You really should not need to be doing this, there is likely to be a much better way of arranging things.

        D Offline
        D Offline
        dalishi
        wrote on last edited by
        #3

        @JonB Hi thanks for your detailed reply. I'm sorry this is a typo, actually the "parent" here in my project is called MainVisualizer, an OpenGL widget as the main widget for the window. I just changed MainVisualizer to MyParent for simple description of the question here. So it should be

        qobject_cast<MyParent *>(parent()); // is OK
        

        But anyway, according to your point, calling parent's methods from child is a bad idea in OOP? Can you help elaborate more on this? I would desperately like to improve my architectural design. Thanks.

        JonBJ jsulmJ 2 Replies Last reply
        0
        • D dalishi

          @JonB Hi thanks for your detailed reply. I'm sorry this is a typo, actually the "parent" here in my project is called MainVisualizer, an OpenGL widget as the main widget for the window. I just changed MainVisualizer to MyParent for simple description of the question here. So it should be

          qobject_cast<MyParent *>(parent()); // is OK
          

          But anyway, according to your point, calling parent's methods from child is a bad idea in OOP? Can you help elaborate more on this? I would desperately like to improve my architectural design. Thanks.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @dalishi said in Access parent from child class:

          qobject_cast<MyParent *>(parent()); // is OK

          It's "OK", but unless you go MyParent *something = qobject_cast<MyParent *>(parent());, and then use something it is a pointless statement as you wrote it.

          calling parent's methods from child is a bad idea in OOP?

          Indeed. Within reason, a child should not need/want to call methods of its parent, and ought to be independent of it. You are doing two "questionable" things here:

          • First, why do you want to access anything about the parent in the child?
          • Second, further you (attempt to) cast the parent to a MainVisualizer *. Why do you do that? Can your MyChild be called with anything other than a MainVisualizer * as its parent anyway? If the answer is it cannot/must not, define your MyChild constructor as MyChild::MyChild(MainVisualizer *parent) anyway. But this still does not answer why you want to call/access stuff from the parent/MainVisualizer at all? There may be a good case, but without knowing what you are trying to achieve it's hard to say.
          D 1 Reply Last reply
          1
          • D dalishi

            @JonB Hi thanks for your detailed reply. I'm sorry this is a typo, actually the "parent" here in my project is called MainVisualizer, an OpenGL widget as the main widget for the window. I just changed MainVisualizer to MyParent for simple description of the question here. So it should be

            qobject_cast<MyParent *>(parent()); // is OK
            

            But anyway, according to your point, calling parent's methods from child is a bad idea in OOP? Can you help elaborate more on this? I would desperately like to improve my architectural design. Thanks.

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @dalishi said in Access parent from child class:

            calling parent's methods from child is a bad idea in OOP?

            Doing so means that your child knows details about its parent. If you later use your child class with another parent (different class) then your code will not work anymore because child makes assumptions about its parent. You're basically introducing tightly coupled code. So, child should not know anything about its parent. If child needs to communicate with parent signals/slots should be used in Qt.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            D 1 Reply Last reply
            1
            • JonBJ JonB

              @dalishi said in Access parent from child class:

              qobject_cast<MyParent *>(parent()); // is OK

              It's "OK", but unless you go MyParent *something = qobject_cast<MyParent *>(parent());, and then use something it is a pointless statement as you wrote it.

              calling parent's methods from child is a bad idea in OOP?

              Indeed. Within reason, a child should not need/want to call methods of its parent, and ought to be independent of it. You are doing two "questionable" things here:

              • First, why do you want to access anything about the parent in the child?
              • Second, further you (attempt to) cast the parent to a MainVisualizer *. Why do you do that? Can your MyChild be called with anything other than a MainVisualizer * as its parent anyway? If the answer is it cannot/must not, define your MyChild constructor as MyChild::MyChild(MainVisualizer *parent) anyway. But this still does not answer why you want to call/access stuff from the parent/MainVisualizer at all? There may be a good case, but without knowing what you are trying to achieve it's hard to say.
              D Offline
              D Offline
              dalishi
              wrote on last edited by
              #6

              @JonB Hi, the case where I want to access the parent is like this: Suppose I have a main widget (MainVisualizer OpenGLWidget), and I have a QDialog (e.g. ConfigDialog) to set some values and the corresponding drawing in the MainVisualizer will change accordingly.

              Previously I would make the ConfigDialog instance the child of the main widget, and in the ConfigDialog once I need to update the drawing, I directly call its parent i.e. the MainVisualizer's method.

              Now according to your comment, I guess I could use signal and slot instead. When the configdialog sends a signal, the mainvisualizer will have a slot to deal with the update drawing. In such way the ConfigDialog (Child) and MainVisualizer (Parent) are independent of each other.

              JonBJ 1 Reply Last reply
              0
              • jsulmJ jsulm

                @dalishi said in Access parent from child class:

                calling parent's methods from child is a bad idea in OOP?

                Doing so means that your child knows details about its parent. If you later use your child class with another parent (different class) then your code will not work anymore because child makes assumptions about its parent. You're basically introducing tightly coupled code. So, child should not know anything about its parent. If child needs to communicate with parent signals/slots should be used in Qt.

                D Offline
                D Offline
                dalishi
                wrote on last edited by
                #7

                @jsulm Hi thanks for the reply. Yes! I assume the child knows who is its parent and that's why I use object_cast to cast the Widget* to MyParent*. It is indeed tightly coupled. I realize this is not the "correct" way to implement with QT. Signal-Slot is the way to go. Thanks.

                1 Reply Last reply
                0
                • D dalishi

                  @JonB Hi, the case where I want to access the parent is like this: Suppose I have a main widget (MainVisualizer OpenGLWidget), and I have a QDialog (e.g. ConfigDialog) to set some values and the corresponding drawing in the MainVisualizer will change accordingly.

                  Previously I would make the ConfigDialog instance the child of the main widget, and in the ConfigDialog once I need to update the drawing, I directly call its parent i.e. the MainVisualizer's method.

                  Now according to your comment, I guess I could use signal and slot instead. When the configdialog sends a signal, the mainvisualizer will have a slot to deal with the update drawing. In such way the ConfigDialog (Child) and MainVisualizer (Parent) are independent of each other.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @dalishi said in Access parent from child class:

                  and in the ConfigDialog once I need to update the drawing, I directly call its parent i.e. the MainVisualizer's method.

                  Yes, that's the bit we don't like, if we are making an OOP effort.

                  Now according to your comment, I guess I could use signal and slot instead. When the configdialog sends a signal, the mainvisualizer will have a slot to deal with the update drawing. In such way the ConfigDialog (Child) and MainVisualizer (Parent) are independent of each other.

                  Exactly that! Or, if you only need to act on the selections in the configuration dialog once the user has made them (possibly several different ones) and pressed some OK button, you could either have the dialog pass back some struct with the various options filled in or you could keep the dialog instance alive for a second (though not shown) and have it provide getter methods which return the values separately for the main window to call. Either way, or with signals & slots, it is the main window which picks up the results and acts on them, not the child which "pokes" them into the parent.

                  If your configuration dialog is modal I think it "more usual" that all changes are gathered together and acted on at the end than changes are made immediately to reflect in the main window (as would be the case with either calling parent methods or acting on signals). I'm not sure I can think of modal dialogs where changes are reflected in the caller at the instant they are made. If it were a modeless dialog/window that might be different.

                  1 Reply Last reply
                  1

                  • Login

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