[SOLVED] Accessing a parent widget's variables
-
[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 declarationclass 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();
}@
wrote on 4 Oct 2018, 14:11 last edited byVery nice! This example works like a charm and has saved me a lot of head aches. Thank you!
-
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.
wrote on 9 Mar 2020, 07:57 last edited byThank you so much . Your answer helped me fix my problem which I was stuck for almost a week. big thank again.