2
votes

I have a list of layouts with items inside. It forms a custom table.

To clean the table i loop through all the layouts and take out the items one by one. Then delete the layout.

  // Delete all items
  QHBoxLayout* row = NULL;
  while( !rowLyts_.isEmpty() && (row = rowLyts_.takeAt(0)) != 0 ) 
  {
    QLayoutItem *item;
    while ((item = row->takeAt(0)) != 0)
      delete item;
    delete row;
  }

This seems to work. But when i start filling the table again i see "ghosts" of the items that were there before cleaning. Most of the times they are between lines, behind the new objets. And they still work.

This happens too when you use only a layout with widgets.

I just want to clean the whole layout of layouts without deleting the content widget. A safe way to clean a layout!.

2
I think you are not deleting the widgets (you insert widgets?). Try to call item->widget() and delete it.OnWhenReady

2 Answers

5
votes

You are deleting the layout items, but not the widgets that the items used to manage. You must delete the widgets. All of the non-layout items will be deleted automatically when you delete the layout itself.

QHBoxLayout* row;
while(!rowLyts_.isEmpty() && (row = rowLyts_.takeAt(0))) 
{
  QLayoutItem *item;
  while ((item = row->takeAt(0))) {
    // The item will be deleted when the layout itself is
    // destructed. Items such as spacers will return a null
    // widget, its deletion is a safe no-op.
    delete item->widget();
    // We don't handle recursion into sublayouts.
    // We check for it so that we won't leak the layout.
    Q_ASSERT(!item->layout());
  }
  delete row;
}

The assert is there to make sure the layout that the code works on matches the implied precondition: there must be no sub-layouts, since the code as written doesn't recurse into them. Any sub-layouts, with their widgets, would leak (not memory leak, but resource leak). The assert will abort the execution if the precondition is violated.

2
votes

clearing the layout can be done by:

QLayoutItem* item;
while ( ( item = row->takeAt( 0 ) ) != NULL )
{
    delete item->widget();
    delete item;
}