Qt模态和非模态对话框
Qt 支持模态对话框和非模态对话框。其中,Qt 有两种级别的模态对话框:应用程序级别的模态和窗口级别的模态,默认是应用程序级别的模态。应用程序级别的模态是指,当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。窗口级别的模态是指,该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。窗口级别的模态尤其适用于多窗口模式。
Qt 使用QDialog::exec()实现应用程序级别的模态对话框,使用QDialog::open()实现窗口级别的模态对话框,使用QDialog::show()实现非模态对话框。
1) 模态对话框:正常(对象在栈上创建)
//1. 模态对话框:正常
QDialog dlg;
dlg.exec();
2) 非模态对话框:会一闪而过(对象在栈上创建)
//2. 非模态对话框:会一闪而过
QDialog dlg;
dlg.show();
这种情况下弹出后一闪而过的原因:
show()函数不会阻塞当前线程,对话框会显示出来,接着show()函数立即返回,代码继续执行槽函数中后续代码。
dialog 是建立在栈上的,show()函数返回后,当槽函数运行结束后,dialog 超出作用域被析构,因此对话框消失了。
知道了此原因,我们将 dialog 改成堆上建立,就不会出现一闪而过的问题了,如下面例子3
3) 非模态对话框:正常(对象在堆上创建)
//3. 非模态对话框:正常
QDialog *dlg = new QDialog;
dlg->setAttribute(Qt::WA_DeleteOnClose);// 设置对话框关闭时,自动销毁对话框
dlg->show();
setAttribute()函数设置对话框关闭时,自动销毁对话框
4) 模态对话框:正常(对象在堆上创建)
//4.模态对话框:正常
QDialog *dlg = new QDialog;
dlg->deleteLater();
dlg->exec();
使用exec()会开始一个新的事件循环,deleteLater()函数会在当前事件循环结束时销毁该对话框
5) 非模态对话框:会一闪而过(对象在堆上创建)
//5. 非模态对话框:会一闪而过
QDialog *dlg = new QDialog;
dlg->deleteLater();
dlg->show();
这种情况下弹出后一闪而过的原因:
如果是 dlg->show(),则只能使用 dlg->setAttribute(Qt::WA_DeleteOnClose);
如果要使用 dialog->deleteLater(),则必须使用 dialog->exec()。
这是因为 deleteLater() 会在事件循环结束时执行,exec()会开始一个新的事件循环,而show() 不开始新的事件循环,所以会一闪而过。
6) 模态对话框:正常(对象在堆上创建)
QDialog *dlg = new QDialog;
dlg->setModal(true);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();