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. [SOLVED] Accessing a parent widget's variables
Forum Update on Monday, May 27th 2025

[SOLVED] Accessing a parent widget's variables

Scheduled Pinned Locked Moved General and Desktop
22 Posts 7 Posters 46.2k 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.
  • P Offline
    P Offline
    planarian
    wrote on 27 Mar 2012, 14:28 last edited by
    #1

    If I have a parent widget and a child widget, shouldn't I be able to access the parent's variables from within the child through the QWidget parent pointer in the child's constructor? So far, when I write an expression that includes parent->someVariable I get an error -- something like "the base is not a pointer."

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JohanSolo
      wrote on 27 Mar 2012, 14:46 last edited by JohanSolo 5 Nov 2015, 07:20
      #2

      I think it's parent() -> someMethod() note the () after parent. And as a general use case you won't be able to access the variables directly, as most of them are protected / private.

      `They did not know it was impossible, so they did it.'
      -- Mark Twain

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sraboisson
        wrote on 27 Mar 2012, 14:53 last edited by
        #3

        I confirm, you should be able to access the parent’s methods and variables from your widget (provided the fact that you pass it to your child's constructor)
        Can you check that you effectively passed a pointer to parent in your child constructor :
        @
        ChildWidget::ChildWidget(QWidget *parent)
        {
        parent->someVariable;
        }
        @
        and NOT:
        @
        ChildWidget::ChildWidget(QWidget parent)
        {
        parent->someVariable;
        }
        @
        Moreover, i agree Johan: in general, you don't access variables directly, but through accessors...
        Hope this will help you.

        [Edit: Wrapped code in @-tags; mlong]

        1 Reply Last reply
        0
        • ? This user is from outside of this forum
          ? This user is from outside of this forum
          Guest
          wrote on 27 Mar 2012, 15:10 last edited by
          #4

          Well, DO'H, your second "snippet" copies the parent as a local, so the -> syntax will not even work even if it wasn't a copy and with the dot syntax you will still access the copy not the actual parent, even if QWidget wasn't non-copyable to begin with. Also, please wrap your code in the appropriate code tags for better readability.

          Acceding the parent through the pointer, passed into the constructor is one way, and as Johan Solo already pointed out, the parent() method is another option, which returns a pointer to the parent, which makes it possible to access the parent outside of the object's constructor.

          1 Reply Last reply
          0
          • P Offline
            P Offline
            planarian
            wrote on 27 Mar 2012, 19:16 last edited by
            #5

            @sraboisson: I double checked and the constructor's parameter does have a * in the right place. The exact error messages are

            bq. invalid use of member (did you forget the '&' ?)

            and

            bq. base operand of '->' is not a pointer

            @Johan Solo and ddriver: I tried a version with parent()->someVariable and received the following error:

            bq. 'class QObject' has no member named 'someVariable'

            I should mention that someVariable is a public static member of the parent class.

            1 Reply Last reply
            0
            • ? This user is from outside of this forum
              ? This user is from outside of this forum
              Guest
              wrote on 27 Mar 2012, 19:26 last edited by
              #6

              Well, obviously you need a pointer to your parent object, not to QObject which is passed in the constructor or returned by parent(). It is your class that inherits QObject that has the variable, what you need is to cast that QObject pointer to your custom class type. Without this procedure, you are limited to the facilities of QObject. You can use either qobject_cast or dynamic_cast just to introduce some runtime type safety, if the cast fails it will return zero, whereas a plain cast will work in the blind and crash you app if something goes wrong.

              @YourParentClass *myParent= qobject_cast<YourParentClass *>(parent()); // or without () if you are in the constructor
              if (myParent)
              myParent->someVariable ...@

              ... or alternatively, if you don't need the pointer object you can simply do:

              @qobject_cast<YourParentClass *>(parent())->someVariable ... @

              Note with the second approach you will neither get autocomplete in the IDE, nor is there a way to check if the cast failed for some reason. Since the outcome of the cast is not known until runtime, if you call someVariable to a NULL pointer, you are likely to crash.

              M 1 Reply Last reply 9 Mar 2020, 07:57
              1
              • D Offline
                D Offline
                dbzhang800
                wrote on 27 Mar 2012, 20:41 last edited by
                #7

                Hi planarian,

                In such case, you had better write your constructor as

                @
                Child::Child(YourParentClass * parent);
                @

                instead of

                @
                Child::Child(QObject * parent);
                @

                Otherwise , you will have to using qobject_cast or static_cast or dynamic_cast

                1 Reply Last reply
                0
                • ? This user is from outside of this forum
                  ? This user is from outside of this forum
                  Guest
                  wrote on 27 Mar 2012, 21:05 last edited by
                  #8

                  That was actually my first idea, but I wasn't sure if it is 100% OK to pass a QObject derived class instead of QObject for parent. Just tested it, it seems to work fine. Not that it is a waste to learn how to use qobject_cast ;) Note, this is only possible in the constructor, outside of it the parent() method will still return a QObject pointer unless you overload the method, or easier - just cast the pointer as mentioned above.

                  1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    planarian
                    wrote on 28 Mar 2012, 13:46 last edited by
                    #9

                    bq. bq. Well, obviously you need a pointer to your parent object, not to QObject which is passed in the constructor

                    Oh, of course! That "Qwidget * Parent" line is so common I never stopped to think about what it. Ok, so this leaves me with two questions:

                    1. How does the parent() function differ from simply using (or casting) the parent pointer? As I pointed out earlier, I get very different errors for each of these.

                    2. Whether I modify the constructor or use a cast, I have to refer to the parent class by name within the child class. Since the parent class already includes the child's header, how do I avoid the circularity of including the parent's header within the child? (I realize this is a C++ issue rather than Qt)

                    1 Reply Last reply
                    0
                    • ? This user is from outside of this forum
                      ? This user is from outside of this forum
                      Guest
                      wrote on 28 Mar 2012, 13:57 last edited by
                      #10

                      Use forward declaration - in the header declare your class, but don't #include its header:

                      @class YourParentClass;@

                      And that's all you will need in the header, forward declaration is a promise to the compiler that you will define YourParentClass later on. This is used to avoid circular dependencies and the associated object redefinition compiler errors. The actual header for your class you include in the cpp file instead.

                      The parent() method by default returns a QObject pointer, which is the lowest compatible facility, the bottom level base class. Your class inherits QObject, either directly or through QWidget, so if you need to access your custom members, you have to do a cast of that QObject pointer to your class type. Parent() will always return a QObject pointer, unless you overload the method yourself. This is not the case with passing a QObject pointer or a pointer to a QObject derived class in the constructor as a parameter, thus in the constructor you can avoid using the parent() method and casting it to your class and instead use pointer to your class directly, it can still be a parent since it "contains" a QObject inside of it. One of the errors you got is you passed your QObject as a copy and not as a pointer, since the -> syntax only works with pointers. Another error you might get is when you try to pass a QObject or derived class as a copy, QObject is by design non-copyable, the constructor is explicit to make sure it does not end up being used as a copy constructor.

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        mlong
                        wrote on 28 Mar 2012, 14:47 last edited by
                        #11

                        bq. How does the parent() function differ from simply using (or casting) the parent pointer?

                        ddriver covered the basics, but I wanted to point out that the "parent" pointer that's in the constructor is arbitrarily named, and as such, may be adding to the confusion on what the details are. Just be aware that parent() is a method that is always named parent() and that the "parent" pointer could just as easily be named anything, like:
                        @
                        MyClass::MyClass(QObject *somethingElse) ...
                        @

                        Software Engineer
                        My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                        1 Reply Last reply
                        0
                        • ? This user is from outside of this forum
                          ? This user is from outside of this forum
                          Guest
                          wrote on 28 Mar 2012, 14:54 last edited by
                          #12

                          Ah yes, parent() is a method that exists in the body of the class, the pointer, passed into the constructor exists only in the body of the constructor, and parent is just the logical identifier/name for the object, you can use whatever name you want.

                          The parent() method and the parent constructor local have nothing to do with each other. I didn't realize there was any confusion about it :)

                          I might add:

                          @MyClass::MyClass(AnyQObjectDerivedClass *somethingElse) {
                          somethingElse->someVariable...@

                          1 Reply Last reply
                          0
                          • P Offline
                            P Offline
                            planarian
                            wrote on 28 Mar 2012, 17:52 last edited by
                            #13

                            bq. Use forward declaration – in the header declare your class, but don’t #include its header:

                            Yes, I've tried a couple different forward declarations, but I can't get rid of the following errors:

                            invalid use of incomplete type 'struct ParentClass'
                            forward declaration of 'struct ParentClass'

                            Incidentally, the child class now includes the line

                            @tempVar = qobject_cast<YourParentClass *>(parent());@

                            where tempVar is of type YourParentClass *.

                            bq. parent is just the logical identifier/name for the object, you can use whatever name you want[...]I didn’t realize there was any confusion about it

                            I'm afraid I'm now even more confused! :) If "Parent" is an arbitrary name, how would Qt decide what the parent of a given widget is if I passed more than one QObject pointer?

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              mlong
                              wrote on 28 Mar 2012, 18:11 last edited by
                              #14

                              In your QObject-derived class, you pass a pointer to a parent object, then it's up to you to pass that pointer's value back to your superclass. This functionality is basic C++ Inheritance stuff and not unique to Qt, though it does apply heavily to Qt.

                              @
                              MyQObjectClass : public QObject
                              {
                              Q_OBJECT
                              public:
                              MyQObjectClass(QObject *theparent = 0);
                              ...
                              }

                              // In the constructor, you call QObject's constructor and pass the parent value upstream.
                              // This is how QObject knows what the parent is.
                              MyQObjectClass::MyQObjectClass(QObject *theparent) : QObject(theparent)
                              {
                              ...
                              // parent() now returns whatever value was passed to the QObject upstream, since
                              // the parent() method originates back up the inheritance tree at the QObject level.
                              }
                              @

                              Software Engineer
                              My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                              1 Reply Last reply
                              0
                              • D Offline
                                D Offline
                                dbzhang800
                                wrote on 28 Mar 2012, 18:27 last edited by
                                #15

                                bq. invalid use of incomplete type ‘struct ParentClass’
                                forward declaration of ‘struct ParentClass’

                                You forget to include the header of "ParentClass" in the *.cpp files which using the class.

                                By the way, Qt is a library of C++, make sure that you have mastered the basis of C++.

                                1 Reply Last reply
                                0
                                • ? This user is from outside of this forum
                                  ? This user is from outside of this forum
                                  Guest
                                  wrote on 28 Mar 2012, 19:20 last edited by
                                  #16

                                  [quote author="planarian" date="1332957173"]

                                  I'm afraid I'm now even more confused! :) If "Parent" is an arbitrary name, how would Qt decide what the parent of a given widget is if I passed more than one QObject pointer?[/quote]

                                  Consider this, names a.k.a identifies MEAN NOTHING at runtime, those are just for the human who writes/reads the code. The compiler uses identifies to get the address of that object in memory, and knowing the type, the entire "topology" of the object in memory is known.

                                  Since you inherit QObject, with inheritance, in the constructor you initialize the base class object as well, as mlong's code snippet indicates. So no matter how many QObject pointers you pass in the constructor of your object, it is the one pointer you use to initialize QObject with that becomes the parent. The reason you might have missed this is Qt Creator automatically initializes QObject when you create a new class inheriting QObject through the new class wizard.

                                  This is not even Qt, this is general C++, as 1+1=2 suggested you should spend some time mastering C++, and Qt will suddenly make more sense :)

                                  1 Reply Last reply
                                  0
                                  • P Offline
                                    P Offline
                                    planarian
                                    wrote on 28 Mar 2012, 20:54 last edited by
                                    #17

                                    bq. it is the one pointer you use to initialize QObject with that becomes the parent

                                    That's the source of my confusion: I simply didn't realize that QObject can never take more than one pointer.

                                    bq. You forget to include the header of “ParentClass” in the *.cpp files which using the class.[...]make sure that you have mastered the basis of C++.

                                    As it currently stands, parent.h includes child.h, parent.cpp includes parent.h, child.h has a "class parent" forward declaration, and child.cpp includes child.h. So I don't believe your diagnosis is correct.

                                    My knowledge of C++ is not so remedial as I may have given the impression, but you are right to suppose that it isn't second nature to me, and your impatience is understandable. I appreciate everyone's time, and will try hard to ensure that any future posts are "on topic."

                                    1 Reply Last reply
                                    0
                                    • ? This user is from outside of this forum
                                      ? This user is from outside of this forum
                                      Guest
                                      wrote on 28 Mar 2012, 21:09 last edited by
                                      #18

                                      [quote author="planarian" date="1332968041"]
                                      That's the source of my confusion: I simply didn't realize that QObject can never take more than one pointer.

                                      As it currently stands, parent.h includes child.h, parent.cpp includes parent.h, child.h has a "class parent" forward declaration, and child.cpp includes child.h. So I don't believe your diagnosis is correct. [/quote]

                                      It is YOU (or eventually Creator) that constructs a QObject inside the QObject derived class, if inheritance is indirect the previous base class is responsble for it, and the parent pointer is passed down the hierarchy until it reaches the bottom base QObject class. Unlike with signals and slots, there is no magic here, no code is generated for you behind the scenes. QObject itself has only 3 constructors, and neither of them can take more than one parent parameter, and the parent parameter is not automatically passed into QObject, it is done in the constructor of the first class that inherits QObject by code, no matter how deep it is before your own class.

                                      Your forward declaration should work the way you have described your situation. Either that is not the case, or there is some other issue, you are best posting your code and the exact error message that goes with it, so we can see what you are trying to do and if necessary test it ourselves. For me accessing parent members from a child totally works.

                                      @// parent header
                                      #ifndef MYPARENT_H
                                      #define MYPARENT_H

                                      #include <QObject>

                                      class MyParent : public QObject
                                      {
                                      Q_OBJECT
                                      public:
                                      explicit MyParent(QObject *parent = 0);
                                      int someVariable;
                                      };
                                      #endif // MYPARENT_H

                                      // parent cpp
                                      #include "myclass.h"

                                      MyParent::MyParent(QObject *parent) :
                                      QObject(parent), someVariable(7) {} // some variable initialized to 7

                                      // child header
                                      #ifndef MYCHILD_H
                                      #define MYCHILD_H

                                      #include <QObject>
                                      class MyParent; //forward declaration

                                      class MyChild : public QObject
                                      {
                                      Q_OBJECT
                                      public:
                                      explicit MyChild(MyParent *parent = 0);
                                      };
                                      #endif // MYCHILD_H

                                      // child cpp
                                      // parent header included here in the child cpp
                                      #include "mychild.h"
                                      #include "myparent.h"

                                      MyChild::MyChild(MyParent *parent) :
                                      QObject(parent)
                                      {
                                      parent->someVariable = 666; // access parent member through pointer and change from 7 to 666
                                      }

                                      //main
                                      #include <QtCore/QCoreApplication>
                                      #include <QDebug>
                                      #include "myparent.h"
                                      #include "mychild.h"

                                      int main(int argc, char *argv[])
                                      {
                                      QCoreApplication a(argc, argv);

                                       MyParent parent;
                                       qDebug() << parent.someVariable; // prints out 7
                                      
                                       MyChild child(&parent);
                                      
                                       qDebug() << parent.someVariable; // prints out 666
                                       qDebug() << dynamic_cast <MyParent *>(child.parent())->someVariable; // casting the QObject * to MyParent * using C++ dynamic cast, no checking, will crash if cast fails, prints out 666
                                       
                                       MyParent * temp = qobject_cast <MyParent *>(child.parent()); //create a local pointer to parent from casting child parent() method with Qt qobject cast
                                       if (temp) { //check if cast succeeded 
                                              temp->someVariable = 333;
                                              qDebug() << parent.someVariable; // prints out 333
                                       }
                                      
                                       return a.exec(&#41;;
                                      

                                      }@

                                      M 1 Reply Last reply 4 Oct 2018, 14:11
                                      1
                                      • P Offline
                                        P Offline
                                        planarian
                                        wrote on 29 Mar 2012, 17:47 last edited by
                                        #19

                                        bq. You forget to include the header of “ParentClass” in the *.cpp files which using the class.

                                        @1+1=2: I'm embarrassed to say that you were dead on after all. The one declaration I was missing was #include "parent.h" in child.cpp but due to my inexperience with forwarding declarations I didn't spot that I hadn't covered all the bases.

                                        @ddriver: Once again you've written a ton of code for my benefit, and although I would have taken a lot longer to figure out this problem without your example, I still feel badly about it. If I lived in Bulgaria, I'd bring a cake to your office, or something....

                                        bq. Unlike with signals and slots, there is no magic here, no code is generated for you behind the scenes.

                                        I see now that moc has spooked me: I've had an unconscious tendency to assume that anything in Qt I don't immediately recognize is a mysterious extension of the language. This thread has done a great deal to clarify my understanding of Qt's boundaries, which is actually more valuable to me than the solution to any particular problem.

                                        Thanks very much!

                                        1 Reply Last reply
                                        0
                                        • ? This user is from outside of this forum
                                          ? This user is from outside of this forum
                                          Guest
                                          wrote on 29 Mar 2012, 19:47 last edited by
                                          #20

                                          [quote author="planarian" date="1333043253"]
                                          @ddriver: Once again you've written a ton of code for my benefit, and although I would have taken a lot longer to figure out this problem without your example, I still feel badly about it. If I lived in Bulgaria, I'd bring a cake to your office, or something....
                                          [/quote]

                                          Well, I am new to programming myself, and that code I did for your sake as much as I did for myself, what a better way to improve than doing so helping others, besides that "ton" of code took only a few minutes, thanks to Qt Creator. So no need to feel bad, or of a cake for that matter, besides I don't eat sweet stuff, it is decremental in far too many ways :P

                                          Don't forget to mark the thread with [SOLVED] once it has ran its course.

                                          1 Reply Last reply
                                          0

                                          1/22

                                          27 Mar 2012, 14:28

                                          • Login

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