QDialog,QWidget实现模态及非模态


https://www.yuque.com/docs/share/15d717b4-d490-42de-ae9f-cd17967eca64

 

 

模态QDialog

QDialog dlg(this); dlg.exec(); 

 

QDialog *pDlg=new QDialog(this); pDlg->setModal(true); pDlg->show(); 

 

非模态QDialog

QDialog *pDlg=new QDialog(this); pDlg->show(); 

 

QDialog实现模态非模态很简单,但是对于QWidget有点迷茫,QWidget中没有exec(),也没有setModal()方式,但是想想看,QWidget作为QDialog的基类,而且QWidget作为“窗口”使用也是在平常不过了,所以会意识到QWidget中是否存在一个相对exec()或setModal()更基本的操作来实现模态和非模态呢?就这样,我找到了setWindowModality(),此函数就是用来设置QWidget运行时的程序阻塞方式的,参数解释如下:

  • Qt::NonModal 不阻塞
  • Qt::WindowModal 阻塞父窗口,所有祖先窗口及其子窗口
  • Qt::ApplicationModal 阻塞整个应用程序

 

看来,setModal()也就是使用setWindowModality()设置Qt::ApplicationModal参数也实现的模态。

如此,要实现QWidget的模态和非模态,只要调用setWindowModality()设置阻塞类型就好了:

QWidget *pWid = new QWidget(this); pWid->setWindowModality(Qt::ApplicationModal); //pWid->setAttribute(Qt::WA_ShowModal, true); pWid->show(); 

 

但是运行发现并未实现模态效果。这里需要注意,当希望使用setWindowModality()将QWidget设置为模态时应该保证QWidget父部件为0,这里修改QWidget *pWid = new QWidget(this);为QWidget *pWid = new QWidget(NULL);在运行就好了。

 

此外,通过setWindowModality()设置模态窗口并不是唯一方式,直接设置部件(或窗口)属性也可以:

pWid->setAttribute(Qt::WA_ShowModal, true)

 

还有很多地方需要注意,当创建QDialog后使用setWindowFlags(Qt::FramelessWindowHint);去掉标题栏时此对话框不再阻塞父窗口,如果需要实现阻塞效果可再次指定Qt::Dialog,即使用:

   

 setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); //这样就会阻塞父窗口了!

但是,这样会影响对话框的半透明(或透明)显示。使用Qt::Dialog之前半透明显示正常:

 

总结

是否是模态和QDialog 和QWidget都可以模态和非模态.exec(), show() 等函数无直接关系,只和窗口属性有关,使用以下两种方式都行:

 

setAttribute(Qt::WA_ShowModal, true);//属性设置 setWindowModality(Qt::ApplicationModal);//设置阻塞类型 ----------------- QDialog中的成员函数setModal(true)及exec()之所以是模态是因为他先设置了窗口属性:setAttribute()再show()


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM