Jasmin Blanchette
Мультистраничные диалоги представляют информацию на страницах, которые отображены на экране так, что только одна страница видима в любой момент времени. Это статья демонстрируют два вида мультистраничного диалога и объясняет, как достигнуть автоматического изменения размеров диалога, когда новая страница становится видимой.
QTabWidget с Автоматическим Изменением размеров |
Стандартный способ представлять много информации в одном окне состоит в том, чтобы использовать QTabWidget. Большинство пользователей знакомо с диалогами вкладок, и нет, вероятно, никакого более лучшего способа скрыть дополнительные параметры от случайных пользователей.
По умолчанию, QTabWidget::minimumSizeHint() возвращает максимальный размер всех существующих страниц, а не только видимой страницы. Например, в диалоге "Find & Replace", приведённом ниже, страница "Replace" задаёт размер целого диалога:
Когда экранное пространство ограничено, возможно, было бы предпочтительнее для диалога изменить свои размеры автоматически, чтобы занять как можно меньше места:
Qt требует довольно небольшого кода, чтобы осуществить автоматическое изменение размеров. Сначала нам необходимо "ignored" и "preferred" размер стратегии на некоторое время, так что давайте сразу объявим, их как глобальные константы:
const QSizePolicy ignored(QSizePolicy::Ignored, QSizePolicy::Ignored); const QSizePolicy preferred(QSizePolicy::Preferred, QSizePolicy::Preferred);
Затем мы реализуем слот currentChanged() в нашем диалоге и подключаем его к сигналу currentChanged() объекта класса QTabWidget:
void FindDialog::currentChanged(QWidget *newPage) { if (newPage == pageFind) { pageFind->setSizePolicy(preferred); pageReplace->setSizePolicy(ignored); } else { pageFind->setSizePolicy(ignored); pageReplace->setSizePolicy(preferred); } layout()->activate(); setFixedSize(minimumSizeHint()); }
Если новая страница "Find", мы устанавливаем размер её стратегии в "Preferred", а размер стратегии "Replace" в "Ignored"; иначе делаем наоборот. Устанавливая размер скрытой стратегии в "ignored", мы гарантируем, что скрытая страница не участвует в формировании минимально рекомендуемого размера QTabWidget.
В конце функции, мы вызываем QLayout::activate(), чтобы повторно вычислить расположение, и устанавливаем размер приложения в минимально рекомендуемый размер. Минимально рекомендуемый размер управляемого расположения приложения вычислен расположением; без вызова QLayout::activate(), minimumSizeHint() возвратил бы значение, основанное на предварительно показанной странице.
Другим подходом к подклассу QTabWidget и повторному осуществлению minimumSizeHint(), может быть уклонение от манипуляций со страничным размером стратегии. Это - вероятно лучший подход, если Вы часто нуждаетесь в многостраничных диалогах. Вы могли бы тогда сделать ваш подкласс, как специфическое дополнение к приложению, чтобы спокойно использовать его в Qt Designer.
LayoutHint и updateGeometry() |
Всякий раз, когда стратегия размера приложения, рекомендуемый размер или минимально рекомендуемый размер изменяется, приложение непосредственно вызывает QWidget::updateGeometry(), который посылает событие LayoutHint в исходное приложение. QLayout ловит такие события и непосредственно вызывает activate(). Все это происходит автоматически, так что мы не должны думать об этом. В нашем примере FindDialog, приведённом выше, мы явно вызывали activate(), потому что мы хотели, чтобы размещение непосредственно вычисляло себя. Мы, возможно, достигнем того же самого результата, вызывая QApplication::sendPostedEvents(0, QEvent:: LayoutHint),гарантирующее, что события LayoutHint непосредственно обработаны и что activate() вызван. |
QWidgetStack с Кнопками |
Ещё одна проблема изменения размеров, расмотренная выше, происходит при подключении управляемого кнопкой QWidgetStack. Приложение объединяет кнопки и QWidgetStack. Клик по кнопке переносит связанную страницу на передний план и изменяет размеры диалога до минимума, требуемого новой страницей. В отличие от основанных на QTabWidget диалогов, эти диалоги обычно постоянно используются пользователем и должны быть небольшими и быстродействующими в использовании.
Вот скриншот из диалога Tool3D с тремя страницами (A, B и C):
Диалог состоит из QButtonGroup (слева) и QWidgetStack (справа). Он был разработан, используя Qt Designer , который представляет "родную" поддержку QWidgetStack в Qt 3.1.
Снова мы создаем хитрый автоматический диалог, изменяющий размеры, используя тот же самый способ, который мы применяли к QTabWidget: установили размеры стратегии скрытых страниц в "ignored".
Вот функция init(), вызываемая конструктором приложения. Имена buttonA, pageA и т.д., были введены в Qt Designer:
void Tool3D::init() { connect(buttonA, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool))); connect(buttonB, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool))); connect(buttonC, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool))); pageA->setSizePolicy(ignored); pageB->setSizePolicy(ignored); pageC->setSizePolicy(ignored); buttonA->toggle(); }
Мы подключаем эти три переключаемых сигнала QToolButtons к слоту диалога buttonToggled; мы устанавливаем размер стратегии всех страниц "ignored"; и мы програмно нажимаем первую кнопку, чтобы перенести страницу A на передний план.
Вот слот buttonToggled(), вызываемый каждым сигналом кнопки toggled():
void Tool3D::buttonToggled(bool on) { if (on) { QToolButton *buttonX = (QToolButton *)sender(); QWidget *newPage; if (buttonX == buttonA) newPage = pageA; else if (buttonX == buttonB) newPage = pageB; else newPage = pageC; QWidget *oldPage = widgetStack->visibleWidget(); if (oldPage != 0) oldPage->setSizePolicy(ignored); newPage->setSizePolicy(preferred); widgetStack->raiseWidget(newPage); layout()->activate(); setFixedSize(minimumSizeHint()); } }
Мы выясняем, какая страница соответствует нажатой кнопке (используя QObject::sender() , модифицируем размер стратегии и переносим новую страницу в начало QWidgetStack, чтобы сделать её видимой. Вызовы activate() и setFixedSize() идентичны тем, что мы сделали для QTabWidget ранее.
Примеры QTabWidget и QWidgetStack имеют много общего - и, фактически, может быть другой пример QWizard. Qt пытается сделать программирование общепринятым, насколько это возможно, так, чтобы знания накопленные вами в использовании одного класса, могли быть использованы снова в других классах.
Copyright © 2003 Trolltech. |