• Fixed (фиксированное) означает, что виджет не может увеличиваться или сжиматься. Размер виджета всегда сохраняет значение его идеального размера;
• Minimum означает, что идеальный размер виджета является его минимальным размером. Размер виджета не может стать меньше идеального размера, но он может при необходимости вырасти для заполнения доступного пространства;
• Maximum означает, что идеальный размер виджета является его максимальным размером. Размер виджета может уменьшаться до его минимального идеального размера;
• Preferred (предпочитаемое) означает, что идеальный размервиджета является его предпочитаемым размером, но виджет может при необходимости сжиматься или растягиваться;
• Expanding (расширяемый) означает, что виджет может сжиматься или растягиваться, но впервую очередь он стремится увеличить свои размеры.
На рис. 6.4 приводится иллюстрация смысла различных политик размеров, причем в качестве примера здесь используется текстовая метка QLabel с текстом «Какой-то текст».
На рисунке политики Preferred и Expanding представлены одинаково. Так в чем же их отличие? При изменении размеров формы, содержащей одновременно виджеты с политикой размера Preferred и Expanding, дополнительное пространство отдается виджетам Expanding, а виджеты Preferred по-прежнему будут иметь свой идеальный размер.
Рис. 6.4. Смысл различных политик размеров.
Существует еще две политики размеров: MinimumExpanding и Ignored. Первая была необходима в некоторых редких случаях для старых версий Qt, но теперь она не применяется; предпочтительнее использовать политику Expanding и соответствующим образом переопределить функцию minimumSizeHint. Последняя напоминает Expanding, но при этом игнорируется идеальный размер виджета и минимальный идеальный его размер.
Кроме горизонтального и вертикального компонентов политики размеров класс QSizePolicy хранит коэффициенты растяжения по горизонтали и вертикали. Эти коэффициенты растяжения могут использоваться для указания того, что различные дочерние виджеты могут растягиваться по-разному при расширении формы. Например, если QTreeWidget располагается над QTextEdit и мы хотим, чтобы QTextEdit был в два раза больше по высоте, чем QTreeWidget, мы можем установить коэффициент растяжения по вертикали для QTextEdit на значение 2, а тот же коэффициент для QTreeWidget — на значение 1.
Другой способ воздействия на компоновку заключается в установке минимального размера, максимального размера или фиксированного размера дочерних виджетов. Менеджер компоновки будет учитывать эти ограничения при компоновке виджетов. Но если этого недостаточно, мы можем всегда создать подкласс дочернего виджета и переопределить функцию sizeHint для получения необходимого нам идеального размера.
Стековая компоновка
Класс QStackedLayout (менеджер стековой компоновки) управляет компоновкой набора дочерних виджетов или «страниц», показывая в каждый конкретный момент только одну из них и скрывая от пользователя остальные. Сам менеджер QStackedLayout невидим и не содержит внутри себя средства для пользователя по изменению страницы. Показанные на рис. 6.5 небольшие стрелки и темно—серая рамка обеспечиваются Qt Designer, чтобы упростить применение этого менеджера компоновки при проектировании формы. Для удобства в Qt предусмотрен класс QStackedWidget, представляющий собой QWidget со встроенным QStackedLayout.
Рис. 6.5. QStackedLayout.
Страницы нумеруются с 0. Если мы хотим сделать какой-нибудь конкретный виджет видимым, мы можем вызвать функцию setCurrentIndex, задавая номер страницы. Номер страницы дочернего виджета можно получить с помощью функции indexOf.
Рис. 6.6. Две страницы диалогового окна Preferences.
Показанное на рис. 6.6 диалоговое окно Preferences (настройка предпочтений) представляет собой пример использования QStackedLayout. Окно диалога состоит из виджета QListWidget слева и менеджера стековой компоновки QStackedLayout справа. Каждый элемент в списке QListWidget соответствует одной странице QStackedLayout. Ниже приводится соответствующий программный код конструктора этого диалогового окна:
01 PreferenceDialog::PreferenceDialog(QWidget *parent)
02 : QDialog(parent)
03 {
04 listWidget = new QListWidget;
05 listWidget->addItem(tr("Web Browser"));
06 listWidget->addItem(tr("Mail & News"));