Qt findChild returning 0
c++, qt, user-interface
Solution
The parent of a `QWidget` must be a `QWidget`. `QLayout` is not a `QWidget`.
Layouts exist to move and resize the children of a `QWidget`. Though you may add child widgets by making calls on the layout, ultimately, their parent will be the `QWidget` that the layout resides on.
To illustrate:
QWidget* widget = new QWidget;
qDebug("Widget: %p", widget);
QHBoxLayout* layout = new QHBoxLayout;
qDebug("Layout: %p", layout);
QWidget* child = new QWidget;
layout->addWidget(child);
qDebug("Child's parent before setLayout: %p", child->parent());
widget->setLayout(layout);
qDebug("Child's parent after setLayout: %p", child->parent());
Output:
Widget: 0x8e1c1e0
Layout: 0x8e1c3f0
Child's parent before setLayout: 0x0
Child's parent after setLayout: 0x8e1c1e0
Problem
I'm currently working on a nice way to use a GUI to modify object contents at run time, project uses Qt. So I thought of passing a `QLayout` to the objects, to let them create their own GUI. As POC, I created this ("display" is the name of the `QVBoxLayout*` parameter): ``` QPushButton* button = new QPushButton(); button->setText("foo"); button->setObjectName("bar"); display->addWidget(button); ``` which works just as fine as expected. But I will need to read what the user typed into the GuI, so this is what I did next: ``` QPushButton *button2 = display->findChild<QPushButton *>(); if(button2) std::cout << button2->objectName().toStdString() << std::endl; ``` here nothing is put out - if() statement is false! ``` QList<QWidget *> widgets = display->findChildren<QWidget *>(); foreach (QWidget* b, widgets) { std::cout << b->objectName().toStdString() << std::endl; } ``` similarly, the `widgets` list is empty. I tried looking through the full member list at: http://doc.qt.digia.com/qt/qvboxlayout-members.html, but findChild/findChildren seems like the best fit to my needs... SOLUTION BELOW This is how I handle it now: instead of passing a `QVBoxLayout` to the GUI creation, a `QWidget` should be passed, in following named "display" as above. ``` QVBoxLayout* layout = new QVBoxLayout(); display->setLayout(layout); QPushButton* button = new QPushButton(); button->setText("foo"); button->setObjectName("bar"); layout->addWidget(button); ``` now to `findChild` / `findChildren`: ``` QPushButton *button2 = display->findChild<QPushButton *>("bar"); if(button2) std::cout << button2->objectName().toStdString() << std::endl; QList<QWidget *> widgets = display->findChildren<QWidget *>(); foreach (QWidget* b, widgets) { std::cout << b->objectName().toStdString() << std::endl; } ``` both methods work for me as expected! (Plus, now the layout can be chosen freely by the GUI creation!)