2014-03-25 153 views
8

我在對話框中有QWidget。在程序運行的過程中,一些QCheckBox *對象添加到佈局是這樣的:Qt - 清除QWidget佈局中的所有小部件

QCheckBox *c = new QCheckBox("Checkbox text"); 
ui->myWidget->layout()->addWidget(c); 

也能正常工作的所有複選框。不過,在我的對話框中,我也有一個QPushButton被稱爲「清除」,當它被按下時,應該清空myWidget以外的所有內容,使其保持空白狀態,就像添加任何QCheckboxes之前一樣。我一直在網上和文檔環顧四周,但我很難找到一種方法來做到這一點。我發現this的問題,我認爲是類似我的問題,並試圖像這樣的解決方案:

void myClass::on_clear_clicked() 
{ 
    while(ui->myWidget->layout()->count() > 0) 
    { 
    QLayoutItem *item = ui->myWidget->layout()->takeAt(0); 
    delete item; 
    } 
} 

然而,這似乎並沒有做任何事情。值得注意的是,我不確定這是否正確地從他的答案中翻譯過來;這個函數應該如何實現還有點不清楚,所以我做了我最好的教育猜測。如果有人知道我可以在上面做些什麼來改變它(或者只是一種不同的方式),我們將不勝感激。

回答

6

約佈局的美妙的事情是,他們自動處理刪除一個小部件的。所以你真正需要的是遍歷這些小部件,你就完成了。既然你想消滅給定小部件的所有孩子,只需做:

for (auto widget: ui->myWidget::findChildren<QWidget*> 
              ({}, Qt::FindDirectChildrenOnly)) 
    delete widget; 

根本不需要擔心佈局。這是否適用於兒童是否由佈局管理。

如果您想要真正正確,您需要忽略作爲子窗口小部件但是獨立窗口的窗口小部件。這將是這種情況,如果這是在通用 庫代碼:

for (auto widget: ui->myWidget::findChildren<QWidget*> 
              ({}, Qt::FindDirectChildrenOnly)) 
    if (! widget->windowFlags() & Qt::Window) delete widget; 

或者,如果你只是想刪除一個給定的佈局管理的兒童及其sublayouts:

void clearWidgets(QLayout * layout) { 
    if (! layout) 
     return; 
    while (auto item = layout->takeAt(0)) { 
     delete item->widget(); 
     clearWidgets(item->layout()); 
    } 
} 
+0

這對我有效,謝謝! :) – thnkwthprtls

8

你可以試試這個:

while (QLayoutItem* item = ui->myWidget->layout()->takeAt(0)) 
    { 
     Q_ASSERT(! item->layout()); // otherwise the layout will leak 
     delete item->widget(); 
     delete item; 
    } 
+0

...對不起,我認爲這是行得通的,但實際上並不是:/謝謝 – thnkwthprtls

+0

這對我很有用。而foreach解決方案甚至沒有編譯。數字... –

+0

item->如果佈局項是間隔區或子佈局,則widget()返回0。這會崩潰 – galinette

1

鑑於你有一個小部件層次結構,它由包含小部件的級聯佈局組成,那麼你最好去下面的內容。

第1步:刪除所有小

QList< QWidget* > children; 
    do 
    { 
     children = MYTOPWIDGET->findChildren< QWidget* >(); 
     if (children.count() == 0) 
      break; 
     delete children.at(0); 
    } 
    while (true); 

步驟2:刪除所有佈局

if (MYTOPWIDGET->layout()) 
    { 
     QLayoutItem* p_item; 
     while ((p_item = MYTOPWIDGET->layout()->takeAt(0)) != nullptr) 
      delete p_item; 
     delete MYTOPWIDGET->layout(); 
    } 

第二步後您的MYTOPWIDGET應乾淨。