QT 煩人的parent該如何理解

2021-08-28 11:42:33 字數 3449 閱讀 4976

對話方塊是gui程式和使用者進行簡短互動的頂層視窗,所謂頂層視窗即始終在主視窗之上顯示。qdialog是qt所有型別的對話方塊視窗的基類,它繼承於qwidget,是一種容器型別元件。

qwidget是所有視窗類的抽象,它也可以生成對話方塊,但是對話方塊是常見的視窗元件,若每次要使用對話方塊,都利用qwidget來生成並設定相關引數,顯然十分繁瑣。所以qt為我們封裝了另外乙個子類qdialog,專門用於生成對話方塊

qdialog類是對話方塊視窗的基類。對話方塊視窗是主要用於短時期任務以及使用者進行簡要通訊的頂級視窗。qdialog可以是模態對話方塊也可以是非模態對話方塊。qdialog支援擴充套件性並且可以提供返回值。他們可以有預設按鈕。qdialog也可以有乙個qsizegrip在它的右下方,使用setsizegripenable()。

注意:qdialog使用父視窗部件的方法和qt中其他類不同。對話方塊總是頂級視窗部件,但是如果它有乙個父物件,它的預設位置就是父物件的中間。他也將和父物件共享工具條條目。

qdialog 是最普通的頂級視窗(乙個不會被嵌入到父視窗部件的視窗部件叫頂級視窗部件)。通常情況下,頂級視窗部件是有框架和標題欄的視窗(儘管使用了一定的視窗部件標記,建立頂級視窗部件時也可以沒有這個修飾)在qt中。qmainwindow和不同的qdialog的子類是最普通的頂級視窗。

非頂級視窗部件就是子視窗部件。他們是他們的父視窗部件中的子視窗。你通常不能在視覺角度從它們的父視窗部件辨別乙個子視窗部件。在qt中的絕大多數其他視窗部件僅僅作為子視窗部件才是有用的。(當然把乙個按鈕作為或者叫做頂級視窗部件也是有可能的,但是絕大多數人喜歡把它們的按鈕放到其他部件當中)

如果是頂級對話方塊,那就是基於qdialog建立,如果是主窗體,就基於qmainwindow,如果不確定,或有可能作為頂級窗體,或有可能嵌入到其他窗體中,則基於qwidget建立。

該如何理解下面段**的第二行qwidget(parent)

1 widget::widget(qwidget *parent) :

2 qwidget(parent)

3

在講解原因之前,先請大家看下面的乙個例子

#include using namespace std;

class base

base(int val):m_num(val)

private:

int m_num;

};

1 上方**定義了乙個基類base,並且有兩個建構函式,乙個是預設建構函式,乙個是有乙個整型引數的建構函式。

class basechild: public base

basechild(int val): base(val)

private:

int m_num;

};

2 上方**定義了乙個basechild類,並繼承base類,同樣的,它也定義了兩個建構函式,乙個預設,乙個有整型引數。

int main(int argc, char *argv)

3 main函式例項化了兩個子類例項,child1,child2。child1呼叫預設建構函式。child2呼叫有整型引數的建構函式。

現在,我們執行程式,會有如下列印:

this is base()!

this is base(int val)!

this is basechild()!

this is basechild(int val)!

看到了嗎,我們發現:

所以我們回頭看basechild的建構函式

basechild(int val): base(val)
細心的同學,可能早就發現了,初始化列表中的base(val)正是呼叫了我們base基類的有參建構函式,而這樣的寫法就剛好是我們開頭**中的那段

widget::widget(qwidget *parent) :qwidget(parent)
所以widget是呼叫了qwidget下面的建構函式

qwidget(qwidget* parent = q_nullptr, qt::windowflags f = qt::windowflags());
所以得出如下總結:

總結:· 如果不指定建構函式,則派生類會呼叫基類的預設建構函式· 派生類建構函式的初始化列表只能初始化派生類成員,不能直接初始化繼承成員,如果想 要呼叫基類的有參建構函式,則可以在派生類的初始化列表中顯示指定
以上總結,也告訴我們,當定義乙個類時,最好為該類定義預設建構函式。至此,我們明白了這個寫法為什麼會這樣寫。

好的,那麼我們又提出乙個問題,「呼叫qwidget(parent)這個建構函式,qwidget父類都做了哪些動作呢?」

下面是qwidget原始碼中的一部分節選:

qwidget::qwidget( qwidget *parent, const char *name, wflags f )

: qobject( parent, name ), qpaintdevice( pdt_widget ),

pal( parent ? parent->palette() // use parent's palette

}

大家從上面可以看出,如果parent引數非空的話,那麼該建構函式使用了其父視窗的調色盤,並且傳送了qchildevent事件,這會讓新的視窗成為parent所指視窗的子視窗,那麼當父視窗被刪除時,子視窗也會自動的被刪除。

初始化列表中的base(vale)正好呼叫了base基類的有參建構函式。

同理,可以理解widget::widget(qwidget *parent) :qwidget(parent)。widget::widget(qwidget *parent) :qwidget(parent)呼叫了qwidget基類的下述建構函式:

qwidget(qwidget*parent =q_nullptr,qt::windowflagsf =qt::windowflags());
如果不指定建構函式,則派生類會呼叫基類的預設建構函式 。派生類建構函式的初始化列表只能初始化派生類成員,不能直接初始化繼承成員,如果想 要呼叫基類的有參建構函式,則可以在派生類的初始化列表中顯示指定。當定義乙個類時,最好為該類定義乙個預設建構函式。對應語法:派生類::派生類建構函式(總引數列表):基類建構函式(引數列表)  //基類建構函式的引數列表是實參。

{派生類中的資料成員初始化;

關於QT構造函式引數parent的解釋

比如說我在標頭檔案裡定義了乙個類 class paintwidget public qwidget 然後在cpp中寫 paintwidget paintwidget qwidget parent qwidget parent 意思是說,重定義父物件。如何重定義呢?看parent引數。當paintwi...

如何刪除那些煩人的亂碼字元

相信很多人在網上瀏覽文章的時候,想拷貝一段文字,一粘帖發現多出來很多亂碼字元,真是討厭啊 就像下面這段文字 在html裡面倒是顯示好好的,怎麼一拷貝出來就變成這副德性了呢,一看html源 發現原因了 inux的時間 4.r p e nt ls6pd e8p nec y 修改linux時間一般涉及到3...

TensorFlow中的Shape如何理解

初學tensorflow時,無法理解其中的shape是什麼意思。筆者查詢一些資料後理解了shape的含義。import tensorflow as tf tf.enable eager execution a tf.constant 1 b tf.constant 1 c a b print c 輸...