Qt - QDialog
1. 描述
QDialog(QWidget的子类)
- 对话框窗口类
- 模态和非模态两种显示方式;
- 非模态 show()来显示
- 模态 exec()来显示,阻塞程序的执行,不能进行焦点切换
- 不可以内嵌到其他窗口的内部
对话窗口是一个顶层窗口,主要用于短期任务和与用户的简短交流。QDialogs 可以是模态的或非模态的。
QDialog(以及任何其他类型为 Qt::Dialog 的小部件)使用父小部件与 Qt 中的其他类略有不同。对话框始终是顶级小部件,但如果它有父级,则其默认位置位于父级顶级小部件的顶部(如果它本身不是顶级)。它还将共享父级的任务栏条目。
1.1 模态对话框
模态对话框是阻止输入到同一应用程序中其他可见窗口的对话框。用于向用户请求文件名或用于设置应用程序首选项的对话框通常是模态的。
当打开应用程序模态对话框时,用户必须完成与对话框的交互并关闭它,然后才能访问应用程序中的任何其他窗口。窗口模态对话框仅阻止访问与对话框关联的窗口,允许用户继续使用应用程序中的其他窗口。
显示模态对话框的最常见方法是调用其 exec() 函数。当用户关闭对话框时, exec() 将提供一个有用的返回值。要关闭对话框并返回适当的值,必须连接一个默认按钮,例如 accept() 槽的 OK 按钮和 reject() 槽的 Cancel 按钮。或者,可以使用 Accepted 或 Rejected 调用 done() 槽。
另一种方法是调用 setModal(true) 或 setWindowModality(),然后调用 show()。与 exec() 不同,show() 立即将控制权返回给调用者。调用 setModal(true) 对于进度对话框特别有用,其中用户必须具有与对话框交互的能力,例如取消长时间运行的操作。如果同时使用 show() 和 setModal(true) 执行长操作,则必须在处理过程中定期调用 QCoreApplication::processEvents() 以使用户能够与对话框进行交互。
1.2 非模态对话框
非模态对话框是独立于同一应用程序中的其他窗口运行的对话框。
使用 show() 显示非模态对话框,它立即将控制权返回给调用者。
1.3 默认按钮
对话框的默认按钮是用户按下 Enter(返回)时按下的按钮。此按钮用于表示用户接受对话框的设置并希望关闭对话框。使用 QPushButton::setDefault() 来设置和控制对话框的默认按钮。
1.4 Esc 键
如果用户在对话框中按下 Esc 键,reject() 将被调用。这将导致窗口关闭:不能忽略关闭事件。
1.5 返回值(模态对话框)
模态对话框通常用于需要返回值的情况,例如指示用户是按下确定还是取消。可以通过调用accept() 或 reject() 槽来关闭对话框,并且 exec() 将根据需要返回 Accepted 或 Rejected。exec() 调用返回对话框的结果。如果对话框没有被销毁,结果也可以从 result() 中获得。
为了修改对话框的关闭行为,可以重新实现函数 accept()、reject() 或 done()。closeEvent() 函数只应重新实现以保留对话框的位置或覆盖标准关闭或拒绝行为。
1.6 代码示例
模态对话框:
void EditorWindow::countWords()
{
WordCountDialog dialog(this);
dialog.setWordCount(document().wordCount());
dialog.exec();
}
非模态对话框:
void EditorWindow::find()
{
if (!findDialog) {
findDialog = new FindDialog(this);
connect(findDialog, &FindDialog::findNext, this, &EditorWindow::findNext);
}
findDialog->show();
findDialog->raise();
findDialog->activateWindow();
}
2. 类型成员
1、enum QDialog::DialogCode:模态对话框返回的值。
- QDialog::Accepted:接受
- QDialog::Rejected:拒绝
3. 属性成员
1、modal : bool
show() 是否应以模态弹出对话框。
默认为 false,并且 show() 将对话框弹出为无模态。将此属性设置为 true 等效于将 QWidget::windowModality 设置为 Qt::ApplicationModal。
exec() 忽略此属性的值并始终以模态弹出对话框。
2、sizeGripEnabled : bool
是否启用大小把手。默认为 false。
启用此属性时,QSizeGrip 将放置在对话框的右下角。
4. 成员函数
1、QDialog(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
对话框始终是顶级小部件,但如果它有父级,则其默认位置位于父级的顶部。 它还将共享父级的任务栏条目。
小部件标志 f 被传递给 QWidget 构造函数。
2、【virtual】void accept()
隐藏模式对话框并将结果代码设置为 Accepted。
3、【信号】void accepted()
使用 QDialog::Accepted 参数调用 accept() 或 done() 接受对话框时,将发出此信号。
请注意,使用 hide() 或 setVisible(false) 隐藏对话框时不会发出此信号。
4、【virtual】void done(int r)
关闭对话框并将其结果代码设置为 r。 finished() 信号将发出 r; 如果 r 是 QDialog::Accepted 或 QDialog::Rejected,accepted() 或 denied() 信号也将分别发出。
若此对话框与 exec() 一起显示,则 done() 也会导致本地事件循环完成,且 exec() 返回 r。
如果设置了 Qt::WA_DeleteOnClose 标志,则 done() 会删除对话框。如果对话框是应用程序的主要小部件,则应用程序终止。如果对话框是最后一个关闭的窗口,则发出 QGuiApplication::lastWindowClosed() 信号。
5、【virtual】int exec()
将对话框显示为模态对话框,在用户关闭它之前一直处于阻塞状态。该函数返回一个 DialogCode 结果。
可见代码里面开启了一个事件循环。
注意:
当对话框有父级时应该应避免使用此功能,而是使用 open()。 与 exec() 不同,open() 是异步的,并且可以防止发生一系列危险的错误(例如,在通过 exec() 打开对话框时删除对话框的父级)。使用 open() 时,可以连接到 QDialog 的 finished() 信号,以便在对话框关闭时得到通知。
QDialog * w = new QDialog(this);
w->setAttribute(Qt::WA_DeleteOnClose);
w->open();
当对话框没有父级时,使用 open() 没有模态效果。
6、【信号】void finished(int result)
当用户或通过调用 done()、accept() 或 reject() 设置对话框的结果代码时,会发出此信号。
使用 hide() 或 setVisible(false) 隐藏对话框时不会发出此信号。
7、【virtual】void open()
将对话框显示为窗口模式对话框,立即返回。
8、【virtual】void reject()
隐藏模式对话框并将结果代码设置为 Rejected。
9、【信号】void rejected()
当对话框被用户拒绝或使用 Rejected 参数调用 reject() 或 done() 时,会发出此信号。
使用 hide() 或 setVisible(false) 隐藏对话框时不会发出此信号。
10、int result()
返回模态对话框的结果代码,Accepted 或 Rejected。
注意:如果对话框是使用 Qt::WA_DeleteOnClose 属性构造的,则不要调用此函数。
11、void setResult(int i)
将模式对话框的结果代码设置为 i。