From 704f03e70e9f1a503d020dc10c8a108a756b5472 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 20 Jan 2019 03:16:38 +0100 Subject: [PATCH] Don't use destroyed wxToolBar in wxFrame::SetToolBar() in wxQt Store QToolBar pointer in wxFrame itself to avoid having to query the already half-destroyed wxToolBar object when SetToolBar() is called from its base class dtor. This fixes crash when toggling the toolbar in the toolbar sample. Closes https://github.com/wxWidgets/wxWidgets/pull/1140 --- include/wx/qt/frame.h | 13 ++++++++++++- src/qt/frame.cpp | 10 ++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/wx/qt/frame.h b/include/wx/qt/frame.h index a0172b62c7..4a603be45c 100644 --- a/include/wx/qt/frame.h +++ b/include/wx/qt/frame.h @@ -19,7 +19,7 @@ class QScrollArea; class WXDLLIMPEXP_CORE wxFrame : public wxFrameBase { public: - wxFrame() { } + wxFrame() { Init(); } wxFrame(wxWindow *parent, wxWindowID id, const wxString& title, @@ -28,6 +28,8 @@ public: long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr) { + Init(); + Create( parent, id, title, pos, size, style, name ); } virtual ~wxFrame(); @@ -56,6 +58,15 @@ protected: virtual void DoGetClientSize(int *width, int *height) const; private: + // Common part of all ctors. + void Init() + { + m_qtToolBar = NULL; + } + + + // Currently active native toolbar. + class QToolBar* m_qtToolBar; wxDECLARE_DYNAMIC_CLASS( wxFrame ); }; diff --git a/src/qt/frame.cpp b/src/qt/frame.cpp index ea29f93145..ec88780779 100644 --- a/src/qt/frame.cpp +++ b/src/qt/frame.cpp @@ -115,11 +115,17 @@ void wxFrame::SetToolBar(wxToolBar *toolbar) else if (toolbar->HasFlag(wxTB_TOP)) { area |= Qt::TopToolBarArea; } else if (toolbar->HasFlag(wxTB_BOTTOM)){ area |= Qt::BottomToolBarArea;} - GetQMainWindow()->addToolBar((Qt::ToolBarArea)area, toolbar->GetQToolBar()); + // We keep the current toolbar handle in our own member variable + // because we can't get it from half-destroyed wxToolBar when it calls + // this function from wxToolBarBase dtor. + m_qtToolBar = toolbar->GetQToolBar(); + + GetQMainWindow()->addToolBar((Qt::ToolBarArea)area, m_qtToolBar); } else if ( m_frameToolBar != NULL ) { - GetQMainWindow()->removeToolBar(m_frameToolBar->GetQToolBar()); + GetQMainWindow()->removeToolBar(m_qtToolBar); + m_qtToolBar = NULL; } wxFrameBase::SetToolBar( toolbar ); }