0

I have a QStackedLayout which contains few QWidget on it. The widgets layout is QVBoxLayout which have also few QPushButton. What I wanted to do is to remove all the widgets inside the QStackedLayout and then delete the widgets and layouts BUT I want all the buttons not to be deleted 'cause I will put them to another widget later.

Here's my code:

while (QLayoutItem *item = m_stacked_layout->takeAt(0)) {
    QWidget *w = item->widget();

    for (int i = 0; i < w->layout()->count(); i++) {
        QPushButton *button = qobject_cast<QPushButton *>(w->layout()->itemAt(i)->widget());
        if (button) {
            w->layout()->removeWidget(button);
        }
    }

    delete w;
    delete item;
}

The application crashes at the line delete w;. And, if I remove the delete lines, application works fine.

iSa
  • 1,144
  • 2
  • 9
  • 21
  • The documentation for QLayoutItem suggests that QLayoutItem::widget() is more of a casting function than returning a member. Thus you shouldn't delete the widget separately from the item. – Hamish Moffatt Apr 28 '15 at 00:45
  • Does the widget also deleted when the QLayoutItem is deleted. – iSa Apr 28 '15 at 06:03
  • Won't work. When you add a widget to a layout, the layout takes ownership of the widget. Delete the layout and you delete the widget. removeWidget does not transfer the ownership back. So your buttons are deleted anyways. – Greenflow Apr 28 '15 at 06:35

1 Answers1

1

BUT I want all the buttons not to be deleted 'cause I will put them to another widget later.

  1. Hide all widgets that you want to transfer
  2. Set parent widget for all this widgets to nullptr
  3. Later... set necessary parent and show widgets

Note: if you want to delete widgets inside some slots, you should use deleteLater method.

Dmitry Sazonov
  • 8,801
  • 1
  • 35
  • 61
  • I replace `delete w` with `w->deleteLater()` and `w->layout()->removeWidget(button)` with `button->setParent(NULL)`, and it works fine now. As I read about `deleteLater`, the object will be deleted once the event loop exited. Is there other way to delete the widget immediately? BTW, the code above was called in `resizeEvent` – iSa Apr 29 '15 at 22:57
  • Not when event loop is exited. But when it continue. You may read Qt documentation about `deleteLater` + when and why it should be used. In most casts you may delete widgets immediately with delete operator. – Dmitry Sazonov Apr 30 '15 at 06:31