Qt之物件樹與所有權

2021-09-23 14:38:08 字數 1426 閱讀 8472

qobjects在乙個物件樹中組織他們自己。當建立乙個qobject時,如果使用了其他物件作為其父物件,那麼,它就會被新增到父物件的children()列表中。這樣一來,當父物件被銷毀時,這個qobject也會被銷毀。事實表明,這個機制非常適合於管理gui物件。例如:乙個qshortcut(鍵盤快捷鍵)物件是相關視窗的乙個子物件,所以,當使用者關閉了這個視窗時,快捷鍵也會被銷毀。

qquickitem是qt quick模組的基本視覺元素,從qobject繼承。但有乙個不同於qobject parent的visual parent的概念,乙個item的visual parent不一定和它的object parent相同。可以參考助手中的concepts - visual parent in qt quick獲取更多資訊。

qwidget是qt widgets模組的基本類,擴充套件了父-子關係。孩子通常成為乙個部件,即:它會顯示在其父窗體的座標系統中,並且由其父窗體的邊界靈活地進行剪裁。例如:當應用程式在關閉提示框(qmessagebox)之後要刪除它時,訊息框的按鈕和標籤也會被刪除。這正是我們所期望的,因為按鈕和標籤是對話方塊的子部件。

當然,也可以自己刪除子物件,他們會從父窗體中移除自己。例如:當使用者移除乙個工具欄時,它可能會導致應用程式刪除q*******中的乙個物件,在這種情況下,工具欄的qmainwindow父窗體將會檢測變化,並重新配置其相應的螢幕空間。

當乙個應用程式看上去或執行起來比較奇怪時,除錯函式qobject:dumpobjecttree()和qobject::dumpobjectinfo()通常比較有用。

當qobjects被建立在堆上(例如:使用new建立)時,他們可以用任何順序構造乙個樹。之後,樹中的物件可以用任何順序被銷毀。當樹中的任何qobject被刪除時,如果它有父物件,析構函式會自動從其父物件中把它刪除。如果它有子物件,析構函式會自動刪除它的每乙個子物件。無論銷毀的順序是什麼,qobject都不會被刪除兩次,

當qobject被建立在棧上時,同樣的行為適用。通常情況下,銷毀順序仍然不會出現問題。看下面的**:

int main()

父視窗(window)和子部件(quit)都屬於qobjects,因為qpushbutton繼承自qwidget,而qwidget繼承自qobject。這段**是正確的:quit的析構函式不會被呼叫兩次,因為c++語言標準(iso/iec 14882:2003)指定本地物件的析構函式以和建構函式相反的順序被呼叫。所以,子部件quit的析構函式首先被呼叫,在window呼叫析構之前,它已經從其父視窗window中刪除自身。

如果我們交換順序,如下所示:

int main()

在這種情況下,銷毀的順序會引起乙個問題。父窗體的析構函式首先被呼叫,因為它最後被建立。然後呼叫子部件(quit)的析構函式,這是不正確的,因為quit是乙個區域性變數,當出了作用域後,其析構函式再次被呼叫,因此會出錯。

8 Qt 之物件樹與所有權

所有視窗及視窗控制項都是從qwidget直接或間接派生出來的。當你建立乙個qobject物件時,可以通過建構函式的引數指定其父物件,此時父物件會把這個qobject物件會自動新增到其children 列表中。當父物件析構的時候,這個列表中的所有 子 物件也會被析構。當我們刪除某個子物件時,父物件會自...

Qt 所有權問題導致多執行緒報錯

問題描述,把定時器放在單獨執行緒中使用,想提高精度。結果報錯 qobject starttimer timers cannot be started from another thread。這種報錯方式,以前剛用多執行緒時候遇見過。知道原因,所以更疑惑,百思不得其解。在q群問,集思廣益。1.多執行緒...

物件生命所有權與TaskPool的歸屬問題

當物件的指標傳入另乙個執行緒時,物件的生命週期管理就變得複雜了,物件不能隨意銷毀自己了,因為其它執行緒可能正在使用它。相當於物件變成全域性的變數了,對於全域性變數我們直觀的感覺就是加鎖,但是加鎖就當程式設計變得不優雅了,需要在這個物件使用的地方都加上鎖。最好的的辦法,應該是通過引用計數來處理了,bo...