对话框是顶层窗口,用于短期任务和与用户的简短通信。
QDialogs可能是模态的,也可能是非模态的;可以有返回值 return value;可以有默认按钮default buttons;可以有一个QSizeGrip 在右下角,用来拖动改变大小,并用setSizeGripEnabled()进行设置。
注 意:
QDialog使用父窗口的方式与Qt中的其他类略有不同。
对话框始终是顶级部件,如果它有父级,它的默认位置将位于父级顶级控件的顶部中心。
它还将共享父任务栏条目。
使用的重载QWidget::setParent()函数可以更改QDialog的从属。使用重载函数将清除指定控件窗口系统属性的窗口标志,还将重置Qt::Dialog标记。
注 意:
为了确保对话框总是在顶部,需要将对话框设置为模态。这也适用于对话框本身的子窗口,为了确保对话框的子窗口也位于对话框顶部,也要使子窗口为模态。
模态对话框
模态对话框是阻止同一应用程序中其他可见窗口接受输入的对话框。用于向用户请求文件名或用于设置应用程序首选项的对话框通常是模态的。
模态对话框打开时,用户必须完成与对话框的交互并关闭它,然后才能访问应用程序中的其他窗口。
显示模态对话框最常见的方法是调用其 exec() 函数。当用户关闭该对话框时, exec() 将提供一个有用的返回值。要关闭对话框并返回相应的值,必须连接一个默认按钮,例如:一个OK按钮连接到接受accept()槽,一个取消按钮连接到拒绝 reject() 槽。
另一种方法是调用设置窗口模态 setModal(true)或设置窗口模态 setWindowModality(),然后show()。与exec() 不同,show()会立即将控制权返回给调用者。调用setModal(true)对于进度对话框特别有用,其中用户必须能够与对话框交互,例如:取消长时间运行的操作。如果您使用show()和setModal(true)一起执行长操作,您必须在处理过程中定期调用QCoreApplication::processEvents()事件,以使用户能够与对话框交互。
无模式对话框
非模态对话框是在同一应用程序中独立于其他窗口运行的对话框。word中的查找和替换对话框通常是非模态的,允许用户与应用程序的主窗口和对话框进行交互。
非模态对话框使用show(),它立即将控制权返回给调用方。
如果您调用show()函数隐藏对话框后,对话框将在其原始位置显示。这是因为窗口管理器决定了程序员没有明确放置的窗口的位置。若要保留用户移动的对话框的位置,请将其位置保存在closeEvent()处理程序,然后将对话框移动到该位置,然后再show()。
默认按钮
默认按钮是指用户按Enter时作出响应的按钮。该按钮用于表示用户接受对话框的设置并想要关闭对话框。使用 QPushButton::setDefault(), QPushButton::isDefault() 和QPushButton::autoDefault() 来设置和控制对话框的默认按钮。
Esc键
如果用户在对话框中按下Esc键,则将调用 QDialog::reject() 将窗口关闭,这是不能忽略的关闭事件。
可扩展性
可扩展性是以两种方式显示对话框。首先显示最常用选项部分的对话框,后续通过用户选择按钮(例如"显示全部"),来显示包含所有选项的完整对话框。
返回值(模态对话框)
模态对话框通常用于需要返回值的情况,例如要求用户按“确定”还是“取消”。可以通过调用接受accept() 或拒绝 reject() 槽函数来关闭一个对话框,exec()根据用户选择返回接受或拒绝的结果。如果该对话框未被销毁,则从结果 result()中也可以获得该结果。
为了修改对话框的关闭行为,您可以重新实现 accept()、 reject() 或done()的函数。关闭事件 closeEvent() 函数只能重新实现保留对话框的位置或重写标准的关闭或拒绝行为。
代码示例
- 模态对话框:
void EditorWindow::countWords()
{
WordCountDialog dialog(this);
dialog.setWordCount(document().wordCount());
dialog.exec(); //显示模态对话框最常见的方法是调用其exec()函数。
}
- 非模态对话框:
void EditorWindow::find()
{
if (!findDialog) {
findDialog = new FindDialog(this);
connect(findDialog, &FindDialog::findNext,
this, &EditorWindow::findNext);
}
findDialog->show(); //非模态对话框使用show(),它立即将控制权返回给调用方。
findDialog->raise(); //将控件置于顶部
findDialog->activateWindow(); //将控件设为“顶层窗体”
}
- 可展开的对话框:
findButton = new QPushButton(tr("&Find"));
moreButton = new QPushButton(tr("&More...")); //点击才会显示全部选项
moreButton->setCheckable(true);
extension = new ExtendedControls;
mainLayout->addWidget(extension);
extension->hide();
connect(moreButton, &QAbstractButton::toggled, extension, &QWidget::setVisible);