自定义对话框因其工作方式的不同而被分为模态和非模态两种。
显示模态对话框需要调用QDialog类的槽函数exec。在模态对话框显示期间,exec函数不返回,这将导致当前应用其它窗口与用户的交互被阻塞。一旦用户关闭了模态对话框,exec函数即返回一个表示被用户点击的按钮的整数——QDialog::Accepted或QDialog::Rejected。通常的做法是将“确定”按钮的clicked信号连接到对话框的accept槽,这将导致点击“确定”按钮关闭对话框时,exec函数返回QDialog::Accepted;同时将“取消”按钮的clicked信号连接到对话框的reject槽,这将导致点击“取消”按钮关闭对话框时,exec函数返回QDialog::Rejected。显示对话框的代码可以根据exec函数的返回值来决定后续执行的操作。比如当exec函数返回QDialog::Accepted时,认定用户在对话框中的操作有效,而当exec函数返回QDialog::Rejected时,权当什么也没发生即可。
显示非模态对话框需要调用QWidget类的槽函数show。show函数会立即返回,并不等待对话框关闭。因此,非模态对话框不会阻塞应用中的其它窗口与用户的交互。事实上,show函数也能用于显示模态对话框。决定一个对话框是模态还是非模态的关键是该对话框的model属性,其值为true即为模态对话框,为false即为非模态对话框。对话框model属性的默认值是false,因此在未经设置的情况下,show函数总是将其显示为非模态对话框。与show函数不同的是,exec函数会忽略对话框的model属性,而总是将其显示为模态对话框。
有关模态与非模态的概念还可以被推广到除对话框以外的其它窗口组件上。任何QWidget及其子类的对象都有一个Qt::WindowModality枚举类型的属性windowModality,表示组件的模态。该属性可取以下值:
windowModality | 模态 | 描述 |
---|---|---|
Qt::NoModal | 非模态 | 不阻塞其它任何窗口的输入 |
Qt::WindowModal | 窗口级模态 | 阻塞所有亲戚窗口(父窗口及各级祖先窗口、兄弟窗口、兄弟窗口的父窗口及各级祖先窗口)的输入 |
Qt::ApplicationModal | 应用级模态 | 阻塞应用程序中所有其它窗口的输入 |
由此可见,在阻塞输入方面,model属性为true的对话框,就相当于windowModality属性为Qt::ApplicationModel的任何组件。