Автор: Reginald Stadlbauer
Перевод: Andi Peredri
Неофициальный перевод статьи Extension Dialogs выполнен с любезного разрешения Trolltech.
Расширенный диалог - это диалоговое окно, имеющее два различных интерфейсных вида: 'простой' и более крупный 'расширенный'. Расширенные диалоги позволяют скрыть многочисленные опции от неквалифицированных и небрежных пользователей и, в то же время, не ограничивать в возможностях настройки опытных пользователей. Такие диалоги можно легко создавать с помощью Qt и Qt Designer.
Изначально расширенный диалог представлен своим 'простым' видом с кнопкой Details >>>. При нажатии на эту кнопку диалоговое окно сменяет свой вид на расширенный, предоставляя доступ к многочисленным опциям, а надпись кнопки сменяется на Details <<<. При повторном нажатии на кнопку диалоговое окно возвращается к своему первоначальному виду.
Ручное управление расположением интерфейсных элементов расширенного диалога является нетривиальной задачей. К счастью, класс QDialog обеспечивает автоматическую компоновку интерфейсных элементов и предлагает функции QDialog::setExtension(), QDialog::showExtension() и QDialog::setOrientation() для поддержки расширенных диалогов.
Создание расширенного диалога в Qt Designer начните с создания простого. Затем, используя шаблон
QWidget, создайте отдельную форму, которая будет использоваться, как расширенная часть диалога. В нашем примере мы назовем ее Extension и сохраним в файле extension.ui. В 'простой' диалог необходимо добавить кнопку Details >>>. В нашем примере мы назовем ее detailsPushButton и свяжем ее сигнал clicked() со слотом toggleExtension().
Затем мы, используя вкладку Source окна Object Explorer, добавим переменную bool extensionShown и включим в исходный код формы файл extension.h.
Если для реализации функциональности диалога вы используете механизм наследования, добавьте следующий код в конструктор подкласса. Если вы пишите код в среде Qt Designer, добавьте этот код в исходный код слота init().
extensionShown = FALSE; setExtension( new Extension( this ) ); setOrientation( Vertical );
Теперь мы реализуем слот toggleExtension(), который вызывается при нажатии на кнопку detailsPushButton:
extensionShown = !extensionShown; showExtension( extensionShown ); QString text = tr( "&Details " ); text += extensionShown ? "<<<" : ">>>"; detailsPushButton->setText( text );
Различие между обычными и расширенными диалогами состоит в том, что некоторые интерфейсные элементы расширенного диалога (радио-кнопки, списки и т.п.) располагаются в его расширении. Поэтому все переменные, которые могут быть установлены пользователем в расширенном диалоге, мы должны проинициализировать в конструкторе или в функции init(). Вот код, соответствующий этому скриншоту:
void MainForm::init() { sessions = FALSE; logging = FALSE; log_filename = QString::null; log_acts = TRUE; log_errs = TRUE; } void MainForm::optionsDlg() { MyDialog *dlg = new MyDialog( this, "dialog", TRUE ); Extension *ext = (Extension*)dlg->extension(); dlg->sessionsCheckBox->setChecked( sessions ); dlg->loggingCheckBox->setChecked( logging ); ext->logfileLineEdit->setText( log_filename ); ext->logActionsCheckBox->setChecked( log_acts ); ext->logErrorsCheckBox->setChecked( log_errs ); if ( dlg->exec() ) { sessions = dlg->sessionsCheckBox->isChecked(); logging = dlg->loggingCheckBox->isChecked(); log_filename = ext->logfileLineEdit->text(); log_acts = ext->logActionsCheckBox->isChecked(); log_errs = ext->logErrorsCheckBox->isChecked(); } delete dlg; }
В представленном выше коде мы использовали явное преобразование типа для большей ясности кода. Стандарт C++ требует, чтобы преобразование типа в таких случаях осуществлялось следующим образом:
Extension *ext = dynamic_cast<Extension*>(dlg->extension()); if ( !ext ) return;
Extension *ext = (Extension*)dlg->extension()->qt_cast("Extension"); if ( !ext ) return;