Qt - clear all widgets inside a QWidget layout

I have a QWidget in a dialog box. During program execution, several QCheckBox * objects are added to the layout:

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

This is great for all checkboxes. However, I also have a QPushButton called "clear" in my dialog box, which when clicked should release everything from myWidget, leaving it blank, just like before any of QCheckboxes was added. I look on the Internet and in documents, but I'm having trouble finding a way to do this. I found this question, which I thought was similar to my problem, and tried to solve them as follows:

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

It didn't seem to do anything. It is worth noting that I'm not sure if this is correctly translated from his answer; it was a little incomprehensible how this function should be implemented, so I did my best. If someone knows what I can change in the above to make it work (or just another way that will work), that would be very helpful.

+8
c ++ qt qwidget
Mar 25 '14 at 18:57
source share
3 answers

The great thing about layouts is that they handle the removal of the widget automatically. So you really need to iterate over the widgets, and you're done. Since you want to destroy all the children of this widget, simply do:

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

No need to worry about layouts at all. This works regardless of whether the children are controlled according to the layout or not.

If you want to be truly correct, you will need to ignore widgets that are child widgets but are standalone windows. This would be true if it were generally library code:

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

Alternatively, if you want to remove only children controlled by this layout and its sublayers:

 void clearWidgets(QLayout * layout) { if (! layout) return; while (auto item = layout->takeAt(0)) { delete item->widget(); clearWidgets(item->layout()); } } 
+6
Mar 25 '14 at 21:42
source share

You can try the following:

  while ( QLayoutItem* item = ui->myWidget->layout()->takeAt( 0 ) ) { Q_ASSERT( ! item->layout() ); // otherwise the layout will leak delete item->widget(); delete item; } 
+9
Mar 25 '14 at 19:07
source share

Given that you have a widget hierarchy consisting of cascading layouts containing widgets, you'd better go for the following.

Step 1: Remove All Widgets

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

Step 2: Remove 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.

+1
Oct 21 '16 at 12:34
source share



All Articles