I have a QWidget
in a dialog. Over the course of the program running, several QCheckBox *
objects are added to the layout like this:
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
QList< QWidget* > children;
do
{
children = MYTOPWIDGET->findChildren< QWidget* >();
if ( children.count() == 0 )
break;
delete children.at( 0 );
}
while ( true );
Step 2: Delete all layouts
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.