Фреймворк Qt предоставляет набор классов, которые позволяют управлять макетом/компоновкой окна приложения и автоматически размещать вложенные виджеты по определенному принципу. Базовым классом для таких контейнеров является класс QLayout. Хотя встроенные виджеты-контейнеры оъватывают довольно большой диапазон ситуаций, тем не менее при необходимости можно создавать свои классы-контейнеры, которые будут унаследованы от QLayout и будут переопределять различные его методы. Основные классы для управления компоновкой:
QVBoxLayout: располагает вложенные виджеты в ряд по вертикали
QHBoxLayout: располагает вложенные виджеты в ряд по горизонтали
QGridLayout: располагает в виде грида/таблицы, где каждый виджет занимает определенную ячейку
QFormLayout: представляет компоновку виджетов в виде формы ввода
QStackedLayout: представляет стек виджетов, в котором одномоменто виден только один виджет
Класс QLayout определяет ряд методов, которые наследуют остальные классы управления компоновкой. Основные из них:
void addWidget(QWidget *w)
: добавляет новый виджет в контейнер
int count()
: возвращает количество элементов в контейнере
QLayoutItem * itemAt(int index)
: возвращает элемент по определенному индексу
QWidget * parentWidget()
: возвращает родительский виджет
removeWidget(QWidget *widget)
: удаляяет виджет из контейнера
QLayoutItem * replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOptions options = Qt::FindChildrenRecursively)
: заменяет один виджет другим
bool setAlignment(QWidget *w, Qt::Alignment alignment)
: устанавливает выравнивание
bool setAlignment(QLayout *l, Qt::Alignment alignment)
: другая версия предыдущего метода
void setContentsMargins(int left, int top, int right, int bottom)
: устанавливает внешние отступы
void setContentsMargins(const QMargins &margins)
: другая версия предыдущего метода
void setSpacing(int)
: устанавливает размер пространства между вложенными виджетами
QLayout::SizeConstraint sizeConstraint()
: устанавливает ограничения по размеру
int spacing()
: возвращает размер пространства между вложенными виджетами
QLayoutItem * takeAt(int index)
: возвращает элемент по индексу
Для связи элемента управления компоновкой с виджетом можно применять различные способы. Во-первых, мы можем установить виджет-контейнер через конструктор QLayout:
QLayout(QWidget *parent = nullptr)
В конструктор передает указатель на виджет, компоновкой которого будет управлять QLayout. Например:
QWidget* widget = new QWidget; QVBoxLayout *layout = new QVBoxLayout(widget);
Здесь элемент QVBoxLayout будет управлять компоновкой контейнера widget. В результате все остальные виджеты добавляются не напрямую в QWidget, а элемент управления компоновкой - QVBoxLayout, объект QVBoxLayout, в свою очередь, располагает вложенные виджеты по определенному принципу.
В качестве альтернативы у виджета можно вызвать метод setLayout(), в который передается объект QLayout:
QWidget* widget = new QWidget; // элемент управления компоновкой для расположения виджетов в ряд по вертикали QVBoxLayout *layout = new QVBoxLayout(); // устанавливаем для widget элемент управления компоновкой widget->setLayout(layout);
Подобным способ может быть полезен, если надо установить нужную компоновку динамически.