topic logo
Qt ⇢ Unit 3

Layout Essentials

vertical layout and stylesheets

Summary

First of the layout units. Explains how to create a simple layout that positions a few labels on the screen.

Background

The applications so far consisted of a single widget. But most applications contain a multitude of nested elements, like controls, display and input widgets.

That’s why the QWidget class can serve as a container for other widgets creating a tree structure in which the root object represents the application window. However, the widgets don’t know how to place and align the child widgets, so by default they just stack them over another creating an incomprehensible mess.

Fortunately there is a sophisticated method to place and align child elements.

New Classes

  • QVBoxLayout: One of the layout classes. It positions widgets vertically. Layouts come with a set of margins that provide padding around the layout items and spacing that do the same between layout items. Even though they fundamentally influence the visuals of an application, they are not derived from the QWidget class and don’t have any direct surface area in the application.
  • QBoxLayout: Base class for the vertical and horizontal box layouts.

Simple Layout

The sample application consist of a root widget that contains three labels which are aligned vertically.

Labels Aligned
Labels Aligned

This time the application window directly inherits the QWidget class and serves as an empty container that the child widgets are placed in.

Initialization

simplelayout.cpp
SimpleLayout::SimpleLayout()
{
    resize(200, 200);
    setStyleSheet("background-color: white");

    auto layout = new QVBoxLayout(this);

    for (int i=0; i<3; i++) {
        auto label = new QLabel("A Label");
        label->setStyleSheet("background-color: lightgray");
        label->setAlignment(Qt::AlignCenter);
        layout->addWidget(label);
    }
}

The constructor first sets the root window to a 200 pixel square. The labels will evenly distribute within this square. An important part of what layouts do is to align items to use the available space. This is especially useful when the user has the audacity to resize the parent window. The contents are gracefully growing with the container creating flexible application user interfaces.

setStyleSheet("background-color: white");

Each widget can be styled with CSS with the “QWidget::setStyleSheet(style)” method. Here the background color is changed to white to visualise what part of the window belongs to the root window, the child labels and the window decoration.

auto layout = new QVBoxLayout(this);

A new layout is created. Passing it the this parameter as parent argument applies this layout on the root widget. Alternatively this argument could also be omitted and then the “QWidget::setLayout()” method used to apply it later.

for (int i=0; i<3; i++) {
    auto label = new QLabel("A Label");
    label->setStyleSheet("background-color: lightgray");
    label->setAlignment(Qt::AlignCenter);
    layout->addWidget(label);
}

The loop creates three labels with the same text, applies a light-gray background to make them stand out from the root widget and adds them to the layout with “QBoxLayout::addWidget(widget)“.

Important

The applications in this tutorial use a lot of throwaway pointers to objects initialized with the “new” keyword. Normally this would be very bad practice as it would create memory holes and make the application leak memory consuming ever more of it. However Qt introduces the concept of parent-child relations. This is applied to any class that derives from the QObject root class. When a class is destroyed, all it’s children and children’s children are destroyed too.

In the sample application, when the labels are added to the layout, they are automatically set as children to the application window. At the time the application window closes, all the child widgets are cleaned up properly and memory leaks are avoided. QObject also declares a set of methods to walk the object tree, so nothing really gets lost in there.

Conclusion

This was just the first unit that deals with layouts. They are an essential part of any Qt application and come in different flavours.

The later part of the unit also hinted the QObject parent-child relation mechanism that is fundamental to the Qt object system. It’s used by practically every part of the framework. This will pop up in several coming units and an intermediate unit will dig a bit deeper into it.