Layout managres in Qt provide mechanisms to control how widgets resize and reposition when their container changes size. A key concept in this behavior is the stretch factor, which defines the relative proportion by which widgets grow or shrink.
Understanding Stretch Factors
- By default, widgets managed by a layout expand equally when space becomes available.
- Custom stretch factors can be assigned to individual widgets or layout rows/columns to control resizing behavior.
- In
QBoxLayout, stretch factors are set usingaddStretch()or via widget-specific policies. - Note: Initial widget sizes are determined before layout application, so visual proportions may only become apparent after resizing the window.
Using QGridLayout
QGridLayout arranges child widgets in a two-dimensional grid. Each widget occupies one or more cells defined by row and column indices.
Stretch factors can also be applied to entire rows or columns in a grid layout:
setRowStretch(row, stretch)controls vertical expansion of a row.setColumnStretch(column, stretch)controls horizontal expansion of a column.
Additionally, layouts can be nested—QGridLayout can contain other layout managers as items, enabling complex UI structures.
Example Implementation
The following code demonstrates a 2Ă—2 grid of buttons with custom minimum sizes and a vertical stretch factor applied to the first row.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
class GridWidget : public QWidget
{
Q_OBJECT
private:
QPushButton buttonA;
QPushButton buttonB;
QPushButton buttonC;
QPushButton buttonD;
void setupGridLayout();
public:
explicit GridWidget(QWidget *parent = nullptr);
~GridWidget() override = default;
};
#endif // WIDGET_H
#include "Widget.h"
#include <QGridLayout>
#include <QSizePolicy>
GridWidget::GridWidget(QWidget *parent)
: QWidget(parent)
, buttonA(this)
, buttonB(this)
, buttonC(this)
, buttonD(this)
{
setupGridLayout();
}
void GridWidget::setupGridLayout()
{
buttonA.setText("Button A");
buttonB.setText("Button B");
buttonC.setText("Button C");
buttonD.setText("Button D");
auto policy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
policy.setHorizontalStretch(1);
policy.setVerticalStretch(1);
buttonA.setSizePolicy(policy);
buttonB.setSizePolicy(policy);
buttonC.setSizePolicy(policy);
buttonD.setSizePolicy(policy);
buttonA.setMinimumSize(160, 50);
buttonB.setMinimumSize(160, 50);
buttonC.setMinimumSize(160, 50);
buttonD.setMinimumSize(160, 50);
auto layout = new QGridLayout(this);
layout->addWidget(&buttonA, 0, 0);
layout->addWidget(&buttonB, 0, 1);
layout->addWidget(&buttonC, 1, 0);
layout->addWidget(&buttonD, 1, 1);
layout->setSpacing(10);
layout->setRowStretch(0, 2); // First row takes twice the vertical space
setLayout(layout);
}
#include <QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
GridWidget window;
window.show();
return app.exec();
}
Key Takeaways
QGridLayoutorganizes widgets in a flexible grid structure.- Widgets can span multiple rows or columns using overloaded
addWidget()variants. - Both
QBoxLayoutandQGridLayoutsupport stretch factors to define relative resizing behavior. - Stretch factors influence how extra space is distributed but do not override minimum or maximum size constraints.