2014-03-25 115 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应干净。