Менеджеры компоновки

Основные менеджеры компоновки виджетов

При размещении виджетов в окне приложения возникает ряд проблем, связанных с размером и размещением виджетов, например:

Ручное размещение виджетов и определение их размеров является весьма муторным делом (необходимо отлавливать изменения размеров окна и в зависимости от новых размеров заново упорядочивать виджеты в окне). Для упрощения размещения виджетов используются менеджеры компоновки (layout managers), которые автоматически организовывает размещение виджетов на экране по определенным правилам.

Для использования менеджеров компоновки необходимо подключить заголовочный файл QLayout.

При этом каждый компоновщик регулирует расположение объектов внутри себя по определенным правилам. Основные менеджеры компоновки следующие:

При изменении размеров окна приложения, виджеты внутри менеджера компоновки будут растягиваться и сжиматься. При этом между виджетами можно вставлять "факторы растяжения" - интервалы, размеры которых также могут меняться.

Для сложного размещения виджетов можно вкладывать менеджеры компоновки внутрь друг друга.

Пример использования компоновщика:

Код примера:

#include <QApplication>
#include <QPushButton>
#include <QLineEdit>
#include <QLayout>

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

    QWidget *window = new QWidget;
    window->setWindowTitle("Calculator");
    QVBoxLayout *mainLayout = new QVBoxLayout();

    QLineEdit *numberEdit = new QLineEdit("0");

    QGridLayout *digitLayout = new QGridLayout();
    for (int i = 1; i < 10; i++) {
        QPushButton *pb = new QPushButton(QString::number(i));
        digitLayout->addWidget(pb, (i - 1) / 3 + 1, (i - 1) % 3 + 1);
    }

    mainLayout->addWidget(numberEdit);
    mainLayout->addLayout(digitLayout);

    window->setLayout(mainLayout);
    window->show();

    return app.exec();
}

В примере используются два компоновщика, один из которых вложен в другой. Заметим, что не требуется явно задавать размеры виджетов в этом примере

Менеджеры компоновки QVBoxLayout и QHBoxLayout

Основной алгоритм работы с менеджерами компоновки следующие:

  1. Создать объект менеджера компоновки.
  2. Добавлять в этот менеджер компоновки последовательно виджеты, промежутки или факторы растяжения, вложенные менеджеры компоновки.
  3. Установить для родительского виджета менеджер компоновки при помощи метода setLayout.

У менеджеров компоновки есть следующие методы:

setMargin(num) -- установить поля (величина отступа между виджетами и границей менеджера компоновки) в num пикселей.

setSpacing(num) -- установить интервал между виджетами внутри менеджера компоновки в num пикселей.

Для добавления внутрь менеджера компоновки различных объектов есть следующие методы:

addWidget(w) -- добавить внутрь менеджера компоновки виджет w (w является параметром типа указатель на виджет). Если вызвать метод addWidget(w, k), то будет добавлен виджет w с фактором растяжения k. Фактор растяжения определяет, насколько увеличивается размер виджета при увеличении размера менеджера компоновки. Если у одного виджета фактор растяжения в два раза больше, чем у другого, то и при увеличении размера окна размер этого виджета будет в два раза больше.

addSpacing(num) -- вставить между виджетами промежуток фиксированной ширины num пикселей.

addStretch(k) -- вставить между виджетами промежуток динамического размера с фактором растяжения k.

addLayout(layout) -- вставить внутрь данного менеджера компоновки вложенный менеджер компоновки (вложенный прямоугольник, внутри которого виджеты размещены соответственно правилам вложенного менеджера компоновки). layout является параметром, типа указатель на менеджер компоновки.

Пример использования менеджера компоновки для размещения виджетов:

#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QLayout>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget * w = new QWidget;
    QPushButton * ButtonA = new QPushButton("A");
    QPushButton * ButtonB = new QPushButton("B");
    QPushButton * ButtonC = new QPushButton("C");
    QHBoxLayout * layout = new QHBoxLayout;
    layout->setMargin(10);
    layout->setSpacing(20);
    layout->addWidget(ButtonA);
    layout->addStretch(1);
    layout->addWidget(ButtonB, 2);
    layout->addStretch(1);
    layout->addWidget(ButtonC);
    w->setLayout(layout);
    w->show();
    return a.exec();
}

Обратите внимание на следующие моменты реализации:

Менеджер компоновки QGridLayout

В менеджере компоновки QGridLayout виджеты размещаются в ячейках таблицы. При добавлении виджета в менеджер компоновки нужно указать номер строки и номер столбца, в котором размещается этот виджет. Виджет может занимать несколько ячеек таблицы (прямоугольную область таблицы).

Методы добавления виджетов в QGridLayout:

addWidget(w, i, j) -- добавить виджет w в строку i, столбец j.

addWidget(w, i, j, rows, columns) -- добавить виджет w в строку i, столбец j, при этом виджет будет занимать область, объединяющую rows строк и columns столбцов таблицы.

Еще одним параметром (последним) можно передать выравнивание виджета относительно ячейки таблицы, например, в виде константы Qt::AlignCenter. Возможные значения выравнивания приведены в документации.

Ограничение размеров виджетов при динамической компоновке

При использовании менеждеров компоновки может потребоваться сделать так, чтобы размеры отдельных виджетов не менялись, или чтобы виджеты имели какие-то минимальные или максимальные допустимые размеры. Для этого у виджета (объекта класса QWidget и всего, что от него унаследовано) есть следующие методы, устанавливающие данные ограничения:

setFixedHeight(h)

setFixedWidth(w)

setFixedSize(w, h)

setMinimumHeight(h)

setMinimumWidth(w)

setMinimumSize(w, h)

setMaximumHeight(h)

setMaximumWidth(w)

setMaximumSize(w, h)

Назначение данных методов понятно из их названий.