在qt里面,其实对于对话框例如qdialog,当我们传递给他一个parents的指针时,则是作为一个子窗口,就是在任务栏里面是和父窗口同样的一个标志,然后如果没有传入,也就是传入null的话,那么就会作为一个顶层的单独的窗口,有自己的任务栏图标。有父窗口的窗口会在父窗口销毁时自动销毁,而单独的窗口则要我们自己来操作,或者设置一个setAttribute(Qt::WA_DeleteOnClose);的属性,让他在被关闭的时候就销毁。
而当窗口创建完毕之后,我们需要显示出来,那么就会有调用show或者exec,前者就是非模态的一个窗口显示,而后者就是模态的。非模态窗口在打开时你仍然能够进行其他窗口的操作,而在模态窗口下他会阻塞所有的本程序内的其他窗口。但是如果简单的使用exec那窗口就只会是一个程序级别的模态窗,那么程序里的所有窗口无论和这个窗口有无关系都会无法相应。
其实qt里对于模态,是分为应用程序级别的模态和窗口级别的模态,默认是应用程序级别的模态。应用程序级别的模态是指,当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。窗口级别的模态是指,该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。QWidget里windowModified : bool这个属性就是记录的标记,通过void setWindowModality(Qt::WindowModality windowModality)这个函数可以进行一个设置。例如:
setWindowModality(Qt::WindowModal);就是设置为窗口级别的模态,然后exec出来的就是一个窗口阻塞的窗口的了。
举个例子,比如当QFileDialog使用的时候只想要阻塞当前的相关窗口,那么:
QFileDialog dlg(this,tr("标题"),QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),tr("(*.txt)"));这样就可以了。
dlg.setWindowModality(Qt::WindowModal);
if(dlg.exec())
当然程序里可能使用较多的会是QMessageBox的static函数来做一些窗口弹出提示信息,但是在这些个类似于QMessageBox::warning之类的函数调用时是没有模态选项的,所以我们还是需要写多几句,构建一个窗口级别的模态窗口:
QMessageBox msgB(QMessageBox::Warning,tr("错误"),tr("xxx."),QMessageBox::Ok,this);
msgB.setWindowModality(Qt::WindowModal);
msgB.exec();