Qt學習記錄--04 Qt的對話框介紹

一 引言:

        熟悉win32(MFC)的小夥伴們會知道, 對話框分爲模態對話框非模態對話框,他們的明顯差異是: 模態對話框在彈出後,會阻塞同一應用程序中其它窗體的輸入,即無法獲取鼠標和鍵盤等響應。模態對話框很常見,比如記事本的“打開文件”功能。當“打開文件”對話框彈出後,我們無法對此外的窗口進行操作的。而非模態對話框在彈出後,其他窗體依舊可以獲取響應。例如記事本的“查找”對話框,我們可以在查找的同時,繼續對記事本的內容進行編輯等操作。


二 Qt的對話框介紹:

        模態和非模態不是Win32所獨有的,在各種不同的平臺下都存在。又有叫法是稱爲模式對話框,無模式對話框等。Qt也引入了此概念,其基本特點與之前描述類似,即:模態對話框就是在其沒有被關閉之前,用戶不能與同一個應用程序的其他窗口進行交互,直到該對話框關閉。對於非模態對話框,當被打開時,用戶既可選擇和該對話框進行交互,也可以選擇同應用程序的其他窗口交互


三 Qt中模態與非模態的實現:

        在Qt中,顯示非模態對話框一般通過QDialog的成員函數show()實現,其默認顯示非模態對話框,但並非一定如此,後面介紹。顯示模態對話框主要有兩種方式,其定義略有差異,一是通過exec()成員函數實現,叫做應用程序級別的模態對話框,其肯定顯示爲模態對話框;二是通過open()成員函數實現,叫做窗口級別的模態對話框,其默認顯示爲模態對話框,但並非一定如此,同樣後面再介紹,下面先看代碼:

#include "widget.h"
#include "ui_widget.h"
#include <QDialog>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

	//! 信號槽
    connect(ui->pushButton_Test, &QPushButton::clicked, this, &Widget::testSlot);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::testSlot()
{
    //! show()
    QDialog *dlg = new QDialog(this);
    dlg->show();
}
        上面實現用show()函數實現非模態對話框的顯示,代碼比較簡單,單擊按鈕彈出對話框,不做過多解釋。
        要實現非模態對話框最要有兩種形式,代碼如下:

void Widget::testSlot()
{
    //! 使用exec()實現模態對話框
    QDialog dlg;
    dlg.exec();
}
void Widget::testSlot()
{
    //! 使用open()實現模態對話框
    QDialog *dlg = new QDialog;
    dlg->open();
}

        首先看Qt中定義的3種模式狀態Qt::NonModalQt::ApplicationModalQt::WindowModal,它們分別代表非模態、應用程序級別的模態和窗口級別的模態。這就引出了上述三個函數的差異。

        下面來具體講述三個函數的特點及差異:

        1.show()函數,默認創建非模態對話框,即默認設置狀態爲Qt::NonModal。另外上面還說過,並非一定是非模態對話框,意思是:可以通過setModal(true)實現模態對話框的創建。此時狀態應爲Qt::ApplicationModal。另外其在被調用後直接返回,爲非阻塞形式。

        2.exec()函數設置狀態爲Qt::ApplicationModel,一定創建模態對話框,對setModal()函數的設置忽略之。其特點是阻塞同一進程的其他窗體,並且被調用後不會直接返回,一直等到關閉對話框。

        3.open()函數,其是在Qt4.5中新加入的,默認設置狀態爲Qt::WindowModal。其同樣可以通過setModal(false)實現非模態對話框的創建。其被調用後直接返回

        

        exec()和open()函數都可以完成模態對話框的創建,他們的差異在哪呢?忽略open()可以創建非模態的特點,針對模態對話框的創建,有如下差異:

        1.exec()不管是否設置父類,其必定會阻塞同一進程中的其他窗體;而open()函數只有在設置其父類(窗體類)後,纔會對其父類所在的進程進行阻塞,即不將this傳入其不會阻塞本進程的其他窗體。

        2.exec()會阻塞等待,直到對話框關閉才返回;而open()調用後直接返回


四 對話框的資源回收

        由於show()函數和open()函數在調用後直接返回,若在棧上分配空間會導致資源的自動回收(當然可以聲明爲類成員變量,不考慮此情況),所以最好在堆上分配,但問題是函數返回後由誰負責回收呢,一般有兩種方法:

        1.將this作爲父類,在其父類析構時會自動銷燬;

        2.進行一下設置:setAttribute (Qt::WA_DeleteOnClose),其作用在對話框關閉後自動銷燬內存佔用。

        針對exec()函數的特點可以爲對話框在棧上分配內存,在關閉對話框後會函數返回後會自動銷燬;而針對在堆上分配的內存,需要通過一下設置進行回收:調用deleteLater()函數,其會在消息循環結束後自動調用進行資源回收。

        

        另外再說一個對話框的一個特點,模態非模態一樣。若在創建時未設置其父類,那麼在顯示時會在任務欄出現對話框的標識,如下圖:

         


        關於Qt對話框的講述先到此爲止了,本文只是簡單介紹,還有很多相關內容未展開(本人也不熟悉~),請自行查閱資料。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章