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

[SOLVED] Accessing a parent widget's variables

Scheduled Pinned Locked Moved General and Desktop
22 Posts 7 Posters 46.4k Views 1 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.
  • P Offline
    P Offline
    planarian
    wrote on 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 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 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 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 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 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
              1
              • P Offline
                P Offline
                planarian
                wrote on 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 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
                  • ? Guest

                    [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 Offline
                    M Offline
                    Mischa schirmer
                    wrote on last edited by
                    #21

                    Very nice! This example works like a charm and has saved me a lot of head aches. Thank you!

                    1 Reply Last reply
                    0
                    • ? Guest

                      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.

                      ma_veasnaM Offline
                      ma_veasnaM Offline
                      ma_veasna
                      wrote on last edited by
                      #22

                      Thank you so much . Your answer helped me fix my problem which I was stuck for almost a week. big thank again.

                      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