From ed09e6a9097546de33dc48e4af1390efd37adda5 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Thu, 17 Jan 2019 22:44:09 +0100 Subject: Desktop: Make filterWidget2 a subobject of MainWindow In commit b0556abdd35f96b816ba11e40bf5707abe0c3ebf, the filter-widget and the filter were connected by a direct function call. This led to a rather obscure crash on application-close with Qt 5.12. The crash is due to the Ui::MainWindow class being a sub-object of MainWindow, but the FilterWidget2 being *not* a subobject. What happens is that after calling the MainWindow destructor, the subobjects are destructed, notably the Ui class. Then the base-class destructor is called (which makes sense, as destructors are called in reverse order of constructors). But: the QObject destructor calls hide() on all still existing child-objects according to Qt's object hierarchy, notably the visible FilterWidget2. Now the FilterWidget2, on hiding, updates the MainWindow, which has already destructed all its subobjects. Crash. Prevent this crash by making FilterWidget2 a subobject of MainWindow and thus have it destructed before running the QObject destructor. Alternative ways would be: 1) Use signal/slot() instead of function calls, as these are automatically removed if an object is destroyed. 2) Make the FilterWidget2 subobject a smart-pointer. Thus, we probably wouldn't have to include the corresponding header. 3) Make the FilterWidget2 subobject a plain pointer and delete it explicitly in the constructor. Reported-by: Jan Mulder Signed-off-by: Berthold Stoeger --- desktop-widgets/mainwindow.cpp | 4 +--- desktop-widgets/mainwindow.h | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 2fd7232a6..d5942a344 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -53,7 +53,6 @@ #include "desktop-widgets/tab-widgets/maintab.h" #include "desktop-widgets/updatemanager.h" #include "desktop-widgets/usersurvey.h" -#include "desktop-widgets/filterwidget2.h" #include "desktop-widgets/simplewidgets.h" #include "profile-widget/profilewidget2.h" @@ -146,7 +145,6 @@ MainWindow::MainWindow() : QMainWindow(), divePlannerSettingsWidget = new PlannerSettingsWidget(this); divePlannerWidget = new DivePlannerWidget(this); plannerDetails = new PlannerDetails(this); - auto *filterWidget2 = new FilterWidget2(); // what is a sane order for those icons? we should have the ones the user is // most likely to want towards the top so they are always visible @@ -195,7 +193,7 @@ MainWindow::MainWindow() : QMainWindow(), registerApplicationState("PlanDive", divePlannerWidget, profileContainer, divePlannerSettingsWidget, plannerDetails ); registerApplicationState("EditPlannedDive", divePlannerWidget, profileContainer, diveList, mapWidget ); registerApplicationState("EditDiveSite", diveSiteEdit, profileContainer, diveList, mapWidget); - registerApplicationState("FilterDive", mainTab, profileContainer, diveList, filterWidget2); + registerApplicationState("FilterDive", mainTab, profileContainer, diveList, &filterWidget2); setStateProperties("Default", enabledList, enabledList, enabledList,enabledList); setStateProperties("AddDive", enabledList, enabledList, enabledList,enabledList); diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index a18738de4..d78fc293e 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -17,6 +17,7 @@ #include "ui_mainwindow.h" #include "ui_plannerDetails.h" #include "desktop-widgets/notificationwidget.h" +#include "desktop-widgets/filterwidget2.h" #include "core/gpslocation.h" #include "core/dive.h" @@ -36,7 +37,6 @@ class ProfileWidget2; class PlannerDetails; class PlannerSettingsWidget; class LocationInformationWidget; -class FilterWidget2; typedef std::pair WidgetProperty; typedef QVector PropertyList; @@ -186,6 +186,7 @@ slots: private: Ui::MainWindow ui; + FilterWidget2 filterWidget2; QAction *actionNextDive; QAction *actionPreviousDive; QAction *undoAction; -- cgit v1.2.3-70-g09d2