Utils: Delete aspect subwidgets one by one

Items deleted in finish() trigger via the connect in registerAspect their
own removal from m_subWidgets, invalidating container iterators used
by deleteAll().

The re-ordering to back-to front does not make a difference, I'd
still to destroy things in reverse construction order.

Change-Id: Ibb17da7cdc67013d744b159aa33fd1d119080e3b
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2021-03-29 14:20:50 +02:00
parent 6a6e7c90df
commit 09f632d4c7

View File

@@ -430,8 +430,9 @@ void BaseAspect::cancel()
void BaseAspect::finish() void BaseAspect::finish()
{ {
qDeleteAll(d->m_subWidgets); // No qDeleteAll() possible as long as the connect in registerSubWidget() exist.
d->m_subWidgets.clear(); while (d->m_subWidgets.size())
delete d->m_subWidgets.takeLast();
} }
bool BaseAspect::hasAction() const bool BaseAspect::hasAction() const
@@ -463,6 +464,11 @@ void BaseAspect::registerSubWidget(QWidget *widget)
{ {
d->m_subWidgets.append(widget); d->m_subWidgets.append(widget);
// FIXME: This interferes with qDeleteAll() in finish() and destructor,
// it would not be needed when all users actually deleted their subwidgets,
// e.g. the SettingsPage::finish() base implementation, but this still
// leaves the cases where no such base functionality is available, e.g.
// in the run/build config aspects.
connect(widget, &QObject::destroyed, this, [this, widget] { connect(widget, &QObject::destroyed, this, [this, widget] {
d->m_subWidgets.removeAll(widget); d->m_subWidgets.removeAll(widget);
}); });
@@ -1475,8 +1481,9 @@ void SelectionAspect::setVolatileValue(const QVariant &val)
void SelectionAspect::finish() void SelectionAspect::finish()
{ {
BaseAspect::finish();
delete d->m_buttonGroup; delete d->m_buttonGroup;
d->m_buttonGroup = nullptr;
BaseAspect::finish();
} }
void SelectionAspect::setDisplayStyle(SelectionAspect::DisplayStyle style) void SelectionAspect::setDisplayStyle(SelectionAspect::DisplayStyle style)