thnkwthprtls thnkwthprtls - 1 month ago 9
C++ Question

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

I have a

QWidget
in a dialog. Over the course of the program running, several
QCheckBox *
objects are added to the layout like this:

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


This works fine for all the checkboxes. However, I also have a
QPushButton
called "clear" in my dialog, which when it is pressed should empty everything out of myWidget, leaving it blank like it was before any of the
QCheckboxes
were added. I've been looking around online and in the docs but I am having trouble finding a way to do this. I found this question which I thought was similar to my problem, and tried their solution like this:

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


This however did not seem to do anything. It's worth noting that I'm not sure if this is translated from his answer correctly; it was a bit unclear how the function given should be implemented, so I made my best educated guess. If anyone knows what I can change in the above to make it work (or just a different way that would work), it would be greatly appreciated.

Answer

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:

foreach (QWidget * w, ui->myWidget::findChildren<QWidget*>()) delete w;

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:

foreach (QWidget * w, ui->myWidget::findChildren<QWidget*>()) 
  if (! w->windowFlags() & Qt::Window) delete w;