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
This commit is contained in:
Vadim Zeitlin
2019-01-20 03:16:38 +01:00
parent 3fb84dfc0c
commit 704f03e70e
2 changed files with 20 additions and 3 deletions

View File

@@ -19,7 +19,7 @@ class QScrollArea;
class WXDLLIMPEXP_CORE wxFrame : public wxFrameBase class WXDLLIMPEXP_CORE wxFrame : public wxFrameBase
{ {
public: public:
wxFrame() { } wxFrame() { Init(); }
wxFrame(wxWindow *parent, wxFrame(wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxString& title, const wxString& title,
@@ -28,6 +28,8 @@ public:
long style = wxDEFAULT_FRAME_STYLE, long style = wxDEFAULT_FRAME_STYLE,
const wxString& name = wxFrameNameStr) const wxString& name = wxFrameNameStr)
{ {
Init();
Create( parent, id, title, pos, size, style, name ); Create( parent, id, title, pos, size, style, name );
} }
virtual ~wxFrame(); virtual ~wxFrame();
@@ -56,6 +58,15 @@ protected:
virtual void DoGetClientSize(int *width, int *height) const; virtual void DoGetClientSize(int *width, int *height) const;
private: private:
// Common part of all ctors.
void Init()
{
m_qtToolBar = NULL;
}
// Currently active native toolbar.
class QToolBar* m_qtToolBar;
wxDECLARE_DYNAMIC_CLASS( wxFrame ); wxDECLARE_DYNAMIC_CLASS( wxFrame );
}; };

View File

@@ -115,11 +115,17 @@ void wxFrame::SetToolBar(wxToolBar *toolbar)
else if (toolbar->HasFlag(wxTB_TOP)) { area |= Qt::TopToolBarArea; } else if (toolbar->HasFlag(wxTB_TOP)) { area |= Qt::TopToolBarArea; }
else if (toolbar->HasFlag(wxTB_BOTTOM)){ area |= Qt::BottomToolBarArea;} 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 ) else if ( m_frameToolBar != NULL )
{ {
GetQMainWindow()->removeToolBar(m_frameToolBar->GetQToolBar()); GetQMainWindow()->removeToolBar(m_qtToolBar);
m_qtToolBar = NULL;
} }
wxFrameBase::SetToolBar( toolbar ); wxFrameBase::SetToolBar( toolbar );
} }