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