Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt findChild returning 0

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!)

like image 461
LDericher Avatar asked Nov 22 '12 19:11

LDericher


1 Answers

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
like image 133
cgmb Avatar answered Oct 23 '22 01:10

cgmb