Qt - 清除QWidget布局中的所有小部件

时间:2014-03-25 18:57:02

标签: c++ qt qwidget

我在对话框中有一个QWidget。在程序运行过程中,几个QCheckBox *对象被添加到布局中,如下所示:

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

这适用于所有复选框。但是,我的对话框中还有一个名为“clear”的QPushButton,当按下它时,应该清除myWidget中的所有内容,使其空白,就像添加任何QCheckboxes之前一样。我一直在网上和文档中寻找,但我很难找到一种方法来做到这一点。我发现this这个问题与我的问题类似,并尝试了这样的解决方案:

void myClass::on_clear_clicked()
{
  while(ui->myWidget->layout()->count() > 0)
  {
    QLayoutItem *item = ui->myWidget->layout()->takeAt(0);
    delete item;
  }
}
然而,这似乎没有做任何事情。值得注意的是,我不确定这是否正确地从他的答案中翻译出来;有点不清楚应该如何实现所给出的功能,所以我做了最好的教育猜测。如果有人知道我可以在上面做些什么来改变它(或者只是以不同的方式工作),那将非常感激。

3 个答案:

答案 0 :(得分:10)

你可以试试这个:

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

答案 1 :(得分: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;

或者,如果您只想删除由给定布局及其子布局管理的子项:

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

答案 2 :(得分: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();
    }

在第2步之后,你的MYTOPWIDGET应该是干净的。