I searched everywhere and found nothing that solved this. I make a QVBoxLayout and then make a web call for data. When the data comes back I add 4 custom widgets to this QVBoxLayout
verticalLayout->addWidget(nsd);
For the first four this works great. Everything appears as needed. However, I want to delete any one of the four widgets then add a widget at the bottom. Deleting works fine
verticalLayout->removeWidget(nsd);
delete nsd;
I know it works fine because then that widget not longer draws to my screen. The problem is that adding the widget is not working entirely. I call the same code
verticalLayout->addWidget(nsd);
and checking verticalLayout->count() tells me there are 4 items. The widget is created with the same parent widget as the ones added before. The paint event of the new widget never gets called. Furthermore the 3 that show on the screen show spaced for 3 items. It's not like there's a hole anywhere. I also tried adding then deleting but it's the same problem. The new item never gets drawn and its size never factored in.
If you want to get rid of a widget completely, you only need to destruct it. You don't have to worry if it was in a layout. If the widget is dynamically allocated, then delete nsd
is all you need, the layout->removeWidget
call is not needed. You also don't have to give widgets any explicit parents - insertion into the layout will set proper parent.
The following works and is safe no matter what is the type of the widget being added/removed. If the deletion had target widget on the call stack, you should use deleteLater
instead of plain delete
. But this can never be the case when you delete it in response to a signal from an unrelated widget, unless the target widget re-enters the event loop (aargh! it shouldn't).
// https://github.com/KubaO/stackoverflown/tree/master/questions/layout-addremove-37814292
#include <QtWidgets>
int main(int argc, char ** argv) {
QApplication app(argc, argv);
QWidget widget;
QVBoxLayout layout(&widget);
QPushButton button;
QLabel label("Hello");
layout.addWidget(&button);
layout.addWidget(&label);
auto onClick = [&]{
if (layout.count() == 3) {
delete layout.itemAt(2)->widget();
button.setText("Add");
} else {
layout.addWidget(new QLabel("Hello too!"));
button.setText("Remove");
}
};
QObject::connect(&button, &QPushButton::clicked, onClick);
onClick();
widget.show();
return app.exec();
}