From 09f632d4c759b1bbb397da8f4e80c6e5d130e3a8 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 29 Mar 2021 14:20:50 +0200 Subject: [PATCH] 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 --- src/libs/utils/aspects.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 98225f44245..5e96b9fe4a8 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -430,8 +430,9 @@ void BaseAspect::cancel() void BaseAspect::finish() { - qDeleteAll(d->m_subWidgets); - d->m_subWidgets.clear(); + // No qDeleteAll() possible as long as the connect in registerSubWidget() exist. + while (d->m_subWidgets.size()) + delete d->m_subWidgets.takeLast(); } bool BaseAspect::hasAction() const @@ -463,6 +464,11 @@ void BaseAspect::registerSubWidget(QWidget *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] { d->m_subWidgets.removeAll(widget); }); @@ -1475,8 +1481,9 @@ void SelectionAspect::setVolatileValue(const QVariant &val) void SelectionAspect::finish() { - BaseAspect::finish(); delete d->m_buttonGroup; + d->m_buttonGroup = nullptr; + BaseAspect::finish(); } void SelectionAspect::setDisplayStyle(SelectionAspect::DisplayStyle style)