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



我有一个对话框中的QWidget。在程序运行的过程中,像这样将几个QCheckBox *对象添加到布局中:

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

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

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

然而,这似乎没有做任何事情。值得注意的是,我不确定这句话是否正确地翻译自他的回答;给出的函数应该如何实现有点不清楚,所以我做了我最好的有根据的猜测。如果有人知道我可以在上面改变什么使它工作(或者只是一种不同的方式,将工作),它将非常感激。

你可以试试:

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

布局的奇妙之处在于它们可以自动处理小部件的删除。因此,您真正需要做的就是遍历这些小部件,这样就完成了。由于您想要清除给定小部件的所有子组件,只需执行:

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());
   }
}

如果你有一个由级联布局组成的小部件层次结构,那么你最好采用以下方法:

步骤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应该是干净的

PySide2解决方案:

from PySide2 import QtWidgets

def clearLayout(layout: QtWidgets.QLayout):
    for i in reversed(range(layout.count())):
        item = layout.itemAt(i)
        if isinstance(item, QtWidgets.QLayout):
            clearLayout(item)
        elif item.widget():
            item.widget().setParent(None)
        else:
            layout.removeItem(item)

相关内容

  • 没有找到相关文章

最新更新