Deleting widget that is in layout
Asked Answered
L

4

6

What will happen if we will run delete widget for widget that is in layout? If this case was written in documentation, please give me the link (I didn't find).

Code example:

QLabel *l1 = new QLabel("1st");
QLabel *l2 = new QLabel("2nd");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(l1);
layout->addWidget(l2);

QWidget *mainWidget = new QWidget;
mainWidget->setLayout(layout);
mainWidget->show();

delete l1;
l2->deleteLater();

Can things that will happen be different for l1 and l2?

Liven answered 18/8, 2012 at 15:59 Comment(0)
L
4

I believe what you are doing is almost same, though neither would properly remove from layout the way you should be doing it. They are still being left as bad references in the layout (if I remember correctly)

The first one simply deletes the item now. The second will delete it once the control returns back to the event loop. But really, the way people usually remove items from a layout is to take them from the layout (giving it a chance to adjust itself), then delete the item and its widget (if you want).

QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
    delete child->widget();
    delete child;
}

Again, the deleting of the widget (child->widget()) is only needed if you want to destroy the widget that was added, in addition to the layout item that was holding it.

Lorelle answered 18/8, 2012 at 18:22 Comment(4)
"They are still being left as bad references in the layout" - no, they aren't. QLayout's listen for events of type ChildRemoved and remove the items accordingly. Simply deleting the widget is safe.Bramwell
Ya I wasnt sure about it. But the take process is a pretty widly accepted patternLorelle
@FrankOsterfeld Please write your answer about this, I'll accept it.Liven
@FrankOsterfeld Can you please post a reference? This seams to not hold for 5.3.2.Moe
L
3

QLayout's listen for events of type ChildRemoved and remove the items accordingly. Simply deleting the widget is safe.

by @FrankOsterfeld here.

Liven answered 7/9, 2012 at 14:47 Comment(1)
The fine print: Never delete this while you're handling an event for the widget you're deleting, or a slot call. The code passing the event to you, or the signal calling your slot, might not be prepared for this. this->deleteLater() is safe in any case.Hildegard
R
1

dont use delete l1 on Qobjects that has active slots connected to them, you will run into a crash. Use: l1->hide(); l1->deleteLater(); It works fine for me

Rivalee answered 8/9, 2012 at 15:11 Comment(0)
J
0

Generally, I don't like to delete Qt widgets, rather remove them from the appropriate layout. (Qt will delete its own widgets if you set the Delete on close window attribute. ) The difference between calling delete and delete later is that delete is the normal C++ delete operation that will call the destructor and free the memory associated with the object.

The deleteLater() method, as discussed in the Qt documentation deletes the object when the event loop is entered.

Jeanmariejeanna answered 18/8, 2012 at 18:45 Comment(2)
"Generally Qt doesn't like it when you delete its widgets." That's not true, one can safely delete widgets.Bramwell
Well spotted @FrankOsterfeld. I edited my answer to be more correct.Jeanmariejeanna

© 2022 - 2024 — McMap. All rights reserved.