2013-07-17 112 views
10

(我使用Qt 4.7,Windows 7,64位)。關於刪除,刪除Qt 4中的小部件和佈局

我創建了一個自定義表。每一行都是帶有小部件的水平佈局。 這些行保存在QList中以方便訪問,也保存在兒童中。行也添加到父窗口小部件中。

如果我調整父控件,我計算出新的大小,刪除了一切,再重新創建它。

我的問題是,我不希望刪除任何部件。只有當我清理桌子時,我纔會這樣做。

因爲我有一個內部的QList和父佈局內的小工具,如何刪除所有控件每一行中,刪除所有的佈局,然後添加那些新的佈局?

如果我這樣做:takeAt(0)爲每個佈局中的每一個元素我有一個QLayoutItem裏面一個小部件...我怎樣才能刪除layoutItem而不刪除插件....我如何刪除小部件不殺死它,不管它是在父母還是在孩子身上?因爲在佈局中有很多刪除方法:removeItem,removeWidget ...,但不是takeWidget ...只是takeAt(),它提供了一個Qlayoutitem。

我嘗試了幾種方法,但我還是看到了小部件無論他們發生了什麼。

問題這一點:

  • 什麼時候一個widget被刪除?如果我從佈局中取出小部件(索引),它是否會被刪除一段時間?如果我在另一個列表中有指向它的指針,它會發生嗎?

  • RemoveAt移除(指數)不執行小部件的刪除方法?

回答

19

好的。我得到了它的工作。 讓我解釋一下如何刪除,保持小工具的作品。

小部件通過它的父級佈局而知道。然後通過佈局移除它。通過這樣做:

layout()->removeAt(widget); 
delete widget; 

如果使用takeAt(指數)在QLayout(或it's兒童),它給你一個QLayoutItem。要訪問裏面的小部件,只需使用widget()。但是沒有辦法刪除它,而不刪除它。所以這種方法是無效的。

在文檔它講述了一個方法來刪除的元素:

QLayoutItem *child; 
while ((child = layout->takeAt(0)) != 0) { 
    ... 
    delete child; 
} 

Qt中要注意的一件特別的事情如下: 如果您有佈局的hyerarchy樹,加入addLayout( )內部佈局,無論您的小部件的插入深度如何,如果佈局和此項目的樹形路徑是從子佈局構建的,則可以將它從子佈局或任何父級佈局中移除。

最簡單的方法是在自定義表中保留指向所有項目的指針列表。當清理表格重建它時,只需在你的部件中執行此操作:

CustomTableItem* item; 
    while (!items_.isEmpty() && ((item = items_.takeFirst()) != 0)){ 
    layout()->removeWidget(item); 
    delete item; // It works no matter where the item is 
    } 

    items_.clear(); // clear the list afterwards. 

而且它的功能完美,它自己也更新佈局。 如果你想保留元素,只需跳過「刪除項目」;並在之後使用它們。

要注意的重要一點是,不同的「刪除」功能的工作方式不同(據我瞭解Qt的文檔)中的QList或類似的部件,並在QLayout。 在QList中,removeAt實際上刪除了該對象。

(Qt的4.7的QList文檔) 「刪除索引位置的項目i。我必須是在列表中(即,0 < = I <尺寸())有效的索引位置。」

在QLayout中,removeWidget或removeItem不會刪除項目/窗口小部件,您有責任將其刪除,就像我以前一樣。

(QT 4.7 QLayout文檔)「從佈局移除的部件部件。在這個調用之後,它是 調用者的責任給小部件合理的幾何形狀或 把小部件回的佈局。」

希望它有幫助。如果你看到任何錯誤,你可以告訴我,我編輯答案!

更多關於刪除此: Other stackoverflow post

+0

layout() - > removeAt(widget);只對QGraphicsLayout存在。你的意思可能是layout() - > removeWidget(widget); – Bim

+0

這也是您可以從佈局中刪除小部件而不刪除它的功能。如果您沒有小部件指針,請執行以下操作: QLayoutItem * item = layout-> itemAt(0); QWidget * widget = item-> widget(); if(widget!= NULL)layout-> removeWidget(widget); //如果你想刪除widget,請執行: widget-> setParent(NULL); 刪除小部件; } (格式化不起作用,但您明白了......) – Bim

+0

僅供參考:由於您必須處理內部C++對象,因此在Python中無效。 – darkgaze

6

Qt中窗口小部件是一個常規的C++對象,並且可以與C++ delete操作者的任何其他對象被刪除:

delete myWidget; 

在Qt總是存在小部件之間的父 - 子關係。當父窗口小部件被銷燬時,它將刪除其所有子窗口。通常,您不需要考慮明確刪除任何小部件,但是需要考慮頂層小部件,即窗口和對話框。 Qt會負責刪除任何子部件。

QList::removeAt(int)不會刪除被刪除的對象,它只是從列表中刪除的對象。如果你也想刪除的對象,你就必須這樣做:

delete myList.takeAt(0); 

這適用於所有功能,如removeAt(int)takeAt(int)takeFirst(),等他們從來沒有刪除對象,他們只從容器中刪除(列表,佈局,Scrollarea等)。在大多數情況下,小部件的所有權將被轉移給調用者(調用者負責在父子關係中斷時刪除小部件),但不要認爲情況總是如此,請始終閱讀函數的文檔。

+0

謝謝!但是我的特殊問題呢:我有一個QBoxLayout。我這樣做:takeAt(int)獲取一個元素。它不是一個小部件,而是一個QLayoutItem。採取我使用的部件。小部件(void)函數。但小部件仍然在裏面。我如何取出小部件並刪除該佈局項?沒有這個功能! – darkgaze

+0

僅供參考這在Python中無效。你也必須關心內部的C++對象。 – darkgaze