简体   繁体   English

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

[英]Qt - Clear all widgets from inside a QWidget's layout

I have a QWidget<\/code> in a dialog.我在对话框中有一个QWidget<\/code> 。 Over the course of the program running, several QCheckBox *<\/code> objects are added to the layout like this:在程序运行的过程中,几个QCheckBox *<\/code>对象被添加到布局中,如下所示:

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

You can try this: 你可以试试这个:

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

The wonderful thing about layouts is that they handle a deletion of a widget automatically. 布局的精彩之处在于它们可以自动处理窗口小部件的删除。 So all you really need is to iterate over the widgets and you're done. 所以你真正需要的是迭代小部件,你就完成了。 Since you want to wipe out all children of a given widget, simply do: 由于您要清除给定窗口小部件的所有子项,只需执行以下操作:

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

No need to worry about layouts at all. 根本不需要担心布局。 This works whether the children were managed by a layout or not. 这适用于孩子是否由布局管理。

If you want to be really correct, you would need to ignore the widgets that are child widgets but are stand-alone windows. 如果你想要真正正确,你需要忽略作为子窗口小部件但是独立窗口的窗口小部件。 This would be the case if this was in general-purpose library code: 如果这是在通用库代码中就是这种情况:

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

Alternatively, if you only want to delete the children managed by a given layout and its sublayouts: 或者,如果您只想删除由给定布局及其子布局管理的子项:

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

Given that you have a widget hierarchy consisting of cascaded layouts containing widgets then you should better go for the following. 鉴于您有一个由包含小部件的级联布局组成的小部件层次结构,那么您最好采用以下方法。

Step 1: Delete all widgets 第1步:删除所有小部件

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

Step 2: Delete all layouts 第2步:删除所有布局

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

After step 2 your MYTOPWIDGET should be clean. 在第2步之后,你的MYTOPWIDGET应该是干净的。

PySide2 Solution:<\/strong> PySide2 解决方案:<\/strong>

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM