5

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

AAEM
  • 1,837
  • 2
  • 18
  • 26
LDericher
  • 295
  • 1
  • 3
  • 12

1 Answers1

5

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
cgmb
  • 4,284
  • 3
  • 33
  • 60