-2

I have a lot of widgets on my window i need to remove all of them except QMenuBar.

ui->menuBar->addAction("Action!");

QWidget *widget = new QWidget(this);
widget->setObjectName("widget");
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(new QPushButton());
layout->addWidget(new QTableWidget(3, 4));`
//now i want to delete all i created 
QList<QWidget*> list = findChildren<QWidget*>();
for (int i = 0; i < list.size(); ++i)
    qDeleteAll(list[i]);

But it's not workink...

Nick Brian
  • 53
  • 5
  • clear next row please: widget->setObjectName("widget"); – Nick Brian Nov 12 '18 at 11:24
  • 2
    I believe, you have to delete only a single pointer, which is `widget` in your example. The rest of widgets will be deleted automatically, because they are children of your "main" widget. – vahancho Nov 12 '18 at 11:36
  • @vahancho yes, you're right. However, OP may still want to use `widget` after clearing it's children. – Rhathin Nov 12 '18 at 11:52
  • `while (!list.isEmpty()) list.takeFirst()->deleteLater();` – scopchanov Nov 12 '18 at 12:15
  • @Rhathin, I don't see such a requirement in the post. He wants to keep the menu bar only, as far as I understand. Anyway, explicitly deleting children in the loop is wrong as it can lead to double deletion of the same pointer. – vahancho Nov 12 '18 at 12:29
  • 1
    Even if you used `qDeleteAll()` correctly, the code would probably crash. Because the list is filled with `findChildren()`, which is recursive. Then sequential deleting items from the list will probably crash if you try to delete a child of already deleted parent (which means the child had already been deleted with the parent). Double delete will fail and probably crash. – HiFile.app - best file manager Nov 13 '18 at 15:30

1 Answers1

1

If you main window inherits from QMainWindow, then you can just do:

delete mainWnd->centralWidget(); 

... and thats all.

But if you inherit your main window from QWidget and the children are in a layout, you just need to go through all items in layout (not just widgets but all layout items) and delete them. Have a look at the most voted answer here except that you probably do not want to delete the layout: Qt - remove all widgets from layout?

In short:

if ( mainWnd->layout() != nullptr )
{
    QLayoutItem* item;
    while ( ( item = mainWnd->layout()->takeAt( 0 ) ) != nullptr )
    {
        delete item->widget();
        delete item;
    }
}

But anyway, if you have certain widgets which you want to dynamically and repeatedly add and remove, it is always better to put them inside a known container (plain QWidget with some margin-less layout) and then just delete the container and create a new container to put new children in it.