Search code examples
layoutqt5parent

QT5: What is the Significance of a Layout's Parent?


I am attempting to write my first program using Qt5. I found a tutorial (zetcode.com/gui/qt5) with a number of examples, which all used dynamic layout creation. I'm trying to create a nested layout configuration, but I'm having a problem with specifying the parent parameter of the layout constructor. When I use the main window as the parent for the main layout and its sub-layouts, I get an error message, apparently telling me that QWidget can have only one QLayout. The window looks OK, but I haven't implemented all my functionality yet (slots and other code), so I don't know what, if anything, is broken. If I omit the parent parameter from the sub-layouts, I get no error messages and the window looks OK as well, but again I'm wondering whether this would affect my subsequent code additions.

Can anyone explain to me the significance of a layout's parent? I've noted that specification of the parent window in the layout's constructor is apparently not sufficient, because all of the examples I've seen call setLayout() at the end of the window's constructor. In particular, will my omission of a parent ever cause problems?


Solution

  • The "rules" are that there can be at most one top level layout on a given widget, and that widgets can be only children of other widgets, not of layouts. So what happens is that:

    • when you set a layout on a widget, the widget will take ownership of that layout;
    • when you add widgets on a layout, these widgets will be reparented to the widget the layout is/gets installed upon;
    • when you add a layout inside another layout, the inner layout becomes a child of the outer layout.

    What you're probably seeing is a side-effect of creating a layout with a widget as parent, as in

    QLayout *layout = new SomeLayout(widget);
    

    This will try to install the layout on widget, and fail in case there's already one. The good news is, you can pretty much ignore passing parents around and rely on the system to do "the right thing". For instance:

    MyWidget::MyWidget(QWidget *parent)
        : QWidget(parent)
    {
        QHBoxLayout *mainLayout = new QHBoxLayout; // top level layout
    
        QVBoxLayout *subLayout1 = new QVBoxLayout; // sub layout 1 stuff
        QPushButton *button = new QPushButton("button");
        subLayout1->addWidget(button);
        // create more widgets...
        mainLayout->addLayout(subLayout1);
    
        QVBoxLayout *subLayout2 = new QVBoxLayout; // sub layout 2 stuff
        QLineEdit *edit = new QLineEdit;
        subLayout2->addWidget(edit);
        mainLayout->addLayout(subLayout2);
    
        setLayout(mainLayout);
    }
    

    This will correctly create a layout hierarchy and a parent/child relation so that nothing will get leaked.