1、模态说明
1.1 模态
阻塞同一应用程序中其它可视窗口输入的对话框。启动模态对话框时,例如弹出对话框强制用户从其他正在进行的业务中聚焦到当前对话框,除了该对话框整个应用程序窗口都无法接受用户响应。
只有关闭和退出该模态界面,才可以访问本应用程序的其他界面和功能。
显示模态对话框最常见的方法是调用其 exec() 函数,当用户关闭对话框,exec() 将提供一个有用的返回值,并且这时流程控制继续从调用 exec() 的地方进行。通常情况下,要获得对话框关闭并返回相应的值,我们连接默认按钮,例如:”确定”按钮连接到 accept() 槽,”取消”按钮连接到 reject() 槽。另外我们也可以连接 done() 槽,传递给它 Accepted 或 Rejected。
我们在阻塞窗口中可以通过调用 accept() 或者是 reject() 函数来是使得 exec() 函数结束阻塞。
1.2 非模态
和同一个程序中其它窗口操作无关的对话框。与模态对话框相反,允许用户同时与应用程序的主窗口和对话框进行交互,调用 show() 来显示非模式对话框,并立即将控制返回给调用者。
1.3 半模态
介于二者之间,代码会继续操作,但是会冻结主界面的交互,他应用继续执行响应。
调用 setModal(true) 或者 setWindowModality(Qt::WindowModal),然后 show()。
1.4 区别
类型 | 模态 | 非模态 | 半模态 |
---|---|---|---|
代码实现 | exec() | show() | setModal(true) + show() |
运行阻塞 | 是 | 否 | 否 |
其他界面操作 | 否 | 是 | 否 |
2、枚举定义
Qt::NonModal
非模态:正常模式Qt::WindowModal
半模态:窗口级模态对话框,阻塞父窗口、父窗口的父窗口及兄弟窗口。Qt::ApplicationModal
模态:应用程序级模态对话框,阻塞整个应用程序的所有窗口。
3、使用
(2)模态
QDialog dialog;
dialog.exec(); //窗口阻塞运行
(2)非模态
QDialog dialog; //不能是局部变量,非模态为非阻塞运行,否则窗口离开作用域就被释放了
dialog.show();
(3)半模态
QDialog dialog; //不能是局部变量,半模态为非阻塞运行,否则窗口离开作用域就被释放了
dialog.setmodal(true);//上句话或者使用dialog.setWindowModality(Qt::WindowModal);
dialog.show();
4、附加内容(QWidget模态设置)
QDialog 实现模态和非模态很简单。
但是QWidget,以及继承QWidget的窗口,不存在 exec(),也没有 setModal() 函数,所有无法实现真正的模态,只能使用一些方法实现半模态。
方法一:
QWidget *pWidget = new QWidget();
pWidget->setWindowModality(Qt::ApplicationModal);
pWidget->show();
方法二:
pWidget->setAttribute(Qt::WA_ShowModal, true); // 属性设置 true:模态 false:非模态
另外使用QWidget时需要注意如下内容:
自定义 QWidget 对话框,通过函数this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);设置了对话框的显示设置后,如果设置了父窗口指针,会导致该对话框在模态显示设置无效,这时需要在该函数中加一个参数Qt::Dialog就可以了。
PS:如果不传父窗口的指针,模态也是有效的,只是这样在任务栏上弹出的窗口也会有一个独立的图标,并且在任务管理其中会多一个任务出现,这样感觉不是太好。设置父窗口后,任务栏和任务管理器中就都合并为一个了。