Qt學習(五) QWidget物件模型

2021-10-07 20:44:23 字數 2347 閱讀 6805

在qt中,所有視窗及視窗控制項都是從qwidget直接或間接派生出來的。

在qt中建立物件的時候會提供乙個parent物件指標,下面來解釋這個parent到底是幹什麼的。

qobject是以物件樹的形式組織起來的。

當你建立乙個qobject物件時,會看到qobject的建構函式接收乙個qobject指標作為引數,這個引數就是 parent,也就是父物件指標。這相當於,在建立qobject物件時,可以提供乙個其父物件,我們建立的這個qobject物件會自動新增到其父物件的children()列表。

當父物件析構的時候,這個列表中的所有物件也會被析構。(注意,這裡的父物件並不是繼承意義上的父類!)

這種機制在 gui 程式設計中相當有用。例如,乙個按鈕有乙個qshortcut(快捷鍵)物件作為其子物件。當我們刪除按鈕的時候,這個快捷鍵理應被刪除。這是合理的。

qwidget是能夠在螢幕上顯示的一切元件的父類。

qwidget繼承自qobject,因此也繼承了這種物件樹關係。乙個孩子自動地成為父元件的乙個子元件。因此,它會顯示在父元件的座標系統中,被父元件的邊界剪裁。例如,當使用者關閉乙個對話方塊的時候,應用程式將其刪除,那麼,我們希望屬於這個對話方塊的按鈕、圖示等應該一起被刪除。事實就是如此,因為這些都是對話方塊的子元件。

當然,我們也可以自己刪除子物件,它們會自動從其父物件列表中刪除。比如,當我們刪除了乙個工具欄時,其所在的主視窗會自動將該工具欄從其子物件列表中刪除,並且自動調整螢幕顯示。

qt 引入物件樹的概念,在一定程度上解決了記憶體問題。

當乙個qobject物件在堆上建立(比如用 new 建立)的時候,qt 會同時為其建立乙個物件樹。不過,物件樹中物件的順序是沒有定義的。這意味著,銷毀這些物件的順序也是未定義的。

任何物件樹中的 qobject物件 delete 的時候,如果這個物件有 parent,則自動將其從 parent 的children()列表中刪除;如果有孩子,則自動 delete 每乙個孩子。qt 保證沒有qobject會被 delete 兩次,這是由析構順序決定的。

在c++的學習中,我們知道,用 new 關鍵字申請的動態記憶體空間如果不及時用 delete 關鍵字進行**會導致記憶體洩漏問題。

而通過 new 關鍵字申請的記憶體如果不用 delete 關鍵字釋放,就不會呼叫析構函式。但如果指定父物件後,且父物件不是用 new 關鍵字申請的動態記憶體空間的話,在程式結束時就會自動呼叫析構函式,而析構的順序又是從物件樹的底層開始的,這時候即使子物件是用 new 關鍵字動態申請記憶體的,也不需要手動釋放子物件的記憶體。

當前,這麼做的前提是:

上面說的都是在堆上建立物件,如果在棧上建立物件,會怎麼樣? 

如果qobject在棧上建立,qt 保持同樣的行為。正常情況下,這也不會發生什麼問題。來看下下面的**片段:

作為父元件的 window 和作為子元件的 quit 都是qobject的子類(事實上,它們都是qwidget的子類,而qwidget是qobject的子類)。這段**是正確的,quit 的析構函式不會被呼叫兩次,因為標準 c++要求,區域性物件的析構順序應該按照其建立順序的相反過程。因此,這段**在超出作用域時,會先呼叫 quit 的析構函式,將其從父物件 window 的子物件列表中刪除,然後才會再呼叫 window 的析構函式。

但是,如果我們使用下面的**:

情況又有所不同,析構順序就有了問題。我們看到,在上面的**中,作為父物件的 window 會首先被析構,因為它是最後乙個建立的物件。在析構過程中,它會呼叫子物件列表中每乙個物件的析構函式,也就是說, quit 此時就被析構了。然後,**繼續執行,在 window 析構之後,quit 也會被析構,因為 quit 也是乙個區域性變數,在超出作用域的時候當然也需要析構。但是,這時候已經是第二次呼叫 quit 的析構函式了,c++ 不允許呼叫兩次析構函式,因此,程式崩潰了。

由此我們看到,qt 的物件樹機制雖然幫助我們在一定程度上解決了記憶體問題,但是也引入了一些值得注意的事情。這些細節在今後的開發過程中很可能時不時跳出來煩擾一下,所以,我們最好從開始就養成良好習慣,在 qt 中,盡量在構造的時候就指定 parent 物件,並且大膽在堆上建立。

QT 學習 五 QT座標系統

圖形檢視框架是基於笛卡爾座標系統的,乙個圖形項在場景中的位置和幾何形狀由x座標和y座標來表示。當使用乙個沒有變換的檢視來觀察場景時,場景中的乙個單元代表螢幕上的乙個畫素。在圖形檢視框架中有3個有效的座標系統 圖形項座標 場景座標和檢視座標。圖形介面程式在座標系統中進行視窗和部件的定位。定位型別 頂級...

QT基礎知識(五)QT物件樹

qt使用物件樹來管理和組織object類或者及其所有子部件。當建立乙個object時,如果使用其他物件作為其父物件,那麼object就會被放置到其父物件的children 列表中。當父物件被銷毀時,這個object也會被銷毀。如下圖 設定樣式風格 brushcolor qt red 顏色 qdebu...

JavaScript建立物件的五種常用模式

所謂工廠模式,就是建立乙個工廠方法,將建立物件的過程用乙個函式進行封裝,即放到工廠方法中,並且在這個函式 工廠方法 內進行物件的初始化,最終返回這個物件。如 function createperson name,age return o 最後返回這個物件 工廠模式的優點 每次建立物件的時候只需呼叫一...