Стек виджетов

Последнее обновление: 08.12.2023

Класс QBoxLayout наследуется от QLayout и представляет расположение виджетов в ряд - по вертикали или по горизонтали. Обычно для этого применяется один из его классов-наследников - QVBoxLayout (расположение по вертикали) или QHBoxLayout (расположение по горизонтали)

Расположение по вертикали с QVBoxLayout

Расположим виджеты в ряд по вертикали. Для этого возьмем простейший проект Qt, где у нас в проекте из файлов кода только файл main.cpp

Компоновка виджетов в Qt и QLayout

И определим в этом файле следующий код:

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget* widget = new QWidget;
    widget -> setWindowTitle("METANIT.COM");
    widget->setMinimumWidth(200);    // минимальная ширина виджета
    widget->setMinimumHeight(150);   // минимальная высота виджета
    // набор вложенных виджетов - кнопок
    QPushButton *btn1 = new QPushButton("Button 1");
    QPushButton *btn2 = new QPushButton("Button 2");
    QPushButton *btn3 = new QPushButton("Button 3");
    QPushButton *btn4 = new QPushButton("Button 4");

    // контейнер для расположения виджетов в ряд по вертикали
    QVBoxLayout *layout = new QVBoxLayout(widget);
    // добавляем виджеты в контейнер
    layout->addWidget(btn1);
    layout->addWidget(btn2);
    layout->addWidget(btn3);
    layout->addWidget(btn4);
    
    widget->show();  // отображаем виджет
    return app.exec();
}

В данном случае корневой элемент приложения или фактически окно представлено объектом QWidget. В качестве вложенных виджетов используем набор кнопок - объектов QPushButton. В конструкторе QPushButton можно установить текст кнопки.

Для расположения по вертикали определяем объект QVBoxLayout:

QVBoxLayout *layout = new QVBoxLayout(widget);

В конструктор контейнера QVBoxLayout передается родительский виджет - указатель widget. Для добавления виджетов в контейнер применяется метод addWidget()

layout->addWidget(btn1);

И мы получим следующую компоновку виджетов:

Компоновка виджетов в Qt по верктикали и QVBoxLayout

Таким образом, контейнер layout будет управлять расположением виджетов внутри объекта widget.

Расположение по горизонтали и QHBoxLayout

Класс QHBoxLayout позволяет расположить вложенные виджеты в ряд по горизонтали:

#include <QApplication>
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget* widget = new QWidget;
    widget -> setWindowTitle("METANIT.COM");
    widget->setMinimumWidth(300);
    widget->setMinimumHeight(150);
    // набор вложенных виджетов - кнопок
    QPushButton *btn1 = new QPushButton("Button 1");
    QPushButton *btn2 = new QPushButton("Button 2");
    QPushButton *btn3 = new QPushButton("Button 3");
    QPushButton *btn4 = new QPushButton("Button 4");

    // контейнер для расположения виджетов в ряд по горизонтали
    QHBoxLayout *layout = new QHBoxLayout(widget);
    // добавляем виджеты в контейнер
    layout->addWidget(btn1);
    layout->addWidget(btn2);
    layout->addWidget(btn3);
    layout->addWidget(btn4);

    widget->show();  // отображаем виджет
    return app.exec();
}

Здесь в принципе то же самое, что и в предыдущем примере, только меняется класс на QHBoxLayout, и соответственно получаем иное расположение виджетов:

Компоновка виджетов в Qt по горизонтали и QHBoxLayout

Методы QBoxLayout и управление вложенными виджетами

Класс QBoxLayout определяет ряд общих методов для управления расположением элементов. Основные из них:

  • void addSpacerItem(QSpacerItem *spacerItem): устанавливает разделитель между виджетами

  • void addSpacing(int size): устанавливает расстояние между виджетами

  • void addStretch(int stretch = 0): устанавливает растяжение виджетов

  • void addStrut(int size): устанавливает ограничение по размеру (минимальный размер)

  • void insertItem(int index, QLayoutItem *item): вставляет элемент по определенному индексу

  • void insertLayout(int index, QLayout *layout, int stretch = 0): добавляет элемент компоновки по определенному индексу

  • void insertSpacerItem(int index, QSpacerItem *spacerItem): устанавливает разделитель между виджетами по определенному индексу

  • void insertSpacing(int index, int size): устанавливает расстояние между виджетами по определенному индексу

  • void insertStretch(int index, int stretch = 0): устанавливает растяжение виджетов по определенному индексу

  • void insertWidget(int index, QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()): добавляет виджет по определенному индексу

  • void setDirection(QBoxLayout::Direction direction): устанавливает направление виджетов

  • void setStretch(int index, int stretch): устанавливает растяжение виджетов по определенному индексу

  • int stretch(int index): возвращает значение растяжения виджетов

Настройка направления виджетов

По умолчанию виджеты располагаются сверху вниз в QVBoxLayout и слева направо в QHBoxLayout. С помощью метода setDirection() это поведение можно изменить. В этот метод передается одна из констант перечисления QBoxLayout::Direction:

  • LeftToRight (слева направо)

  • RightToLeft (справа налево)

  • TopToBottom (сверху вниз)

  • BottomToTop (снизу вверх)

Например, расположим виджеты справа налево:

#include  <QApplication >
#include  <QWidget >
#include  <QHBoxLayout >
#include  <QPushButton >

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget* widget = new QWidget;
    widget -> setWindowTitle("METANIT.COM");

    QPushButton *btn1 = new QPushButton("Button 1");
    QPushButton *btn2 = new QPushButton("Button 2");
    QPushButton *btn3 = new QPushButton("Button 3");

    QHBoxLayout *layout = new QHBoxLayout(widget);
    layout- >addStrut(100); // минимальный размер
    layout- >addWidget(btn1);
    layout- >addWidget(btn2);
    layout- >addWidget(btn3);
    // расположение справа налево
    layout- >setDirection(QBoxLayout::Direction::RightToLeft);

    widget- >show();
    return app.exec();
}
Направление виджетов в QBoxLayout в QT

Установка растяжения

Методы addStretch/insertStretch/setStretch позволяют установить растяжимое пространство между виджетами в виде объекта QSpacerItem. addStretch() добавляет растяжимое пространство после последнего виджета. В качестве параметра передается фактор растяжения. Методы insertStretch()/setStretch() устанавливают индекс, по которому надо добавить растяжение. Например:

#include  <QApplication >
#include  <QWidget >
#include  <QVBoxLayout >
#include  <QPushButton >

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget* widget = new QWidget;
    widget -> setWindowTitle("METANIT.COM");

    QPushButton *btn1 = new QPushButton("Button 1");
    QPushButton *btn2 = new QPushButton("Button 2");
    QPushButton *btn3 = new QPushButton("Button 3");

    QVBoxLayout *layout = new QVBoxLayout(widget);
    layout- >addStrut(200); // минимальный размер
    layout- >addWidget(btn1);
    layout- >addWidget(btn2);
    layout- >addWidget(btn3);
    layout- >addStretch(10);
    layout- >insertStretch(2, 10);

    widget- >show();
    return app.exec();
}

Здесь добавляем растяжение после последнего виджета:

layout- >addStretch(10);

И добавляем растяжение перед вторым виджетом

layout- >insertStretch(2, 10);

То есть при растяжении окна получим следующую компоновку:

Растяжение пространства между виджетами в QBoxLayout в QT

Если передается отрицательный индекс, то отсчет идет с конца.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850