@@ -971,9 +971,13 @@ def _onClose(self, event):
971971 _log .debug ("%s - onClose()" , type (self ))
972972 self .canvas .close_event ()
973973 self .canvas .stop_event_loop ()
974- Gcf .destroy (self )
975- if self :
976- self .Destroy ()
974+ # set FigureManagerWx.frame to None to prevent repeated attempts to
975+ # close this frame from FigureManagerWx.destroy()
976+ self .figmgr .frame = None
977+ # remove figure manager from Gcf.figs
978+ Gcf .destroy (self .figmgr )
979+ # Carry on with close event propagation, frame & children destruction
980+ event .Skip ()
977981
978982 def GetToolBar (self ):
979983 """Override wxFrame::GetToolBar as we don't have managed toolbar"""
@@ -990,11 +994,8 @@ def Destroy(self, *args, **kwargs):
990994 # MPLBACKEND=wxagg python -c 'from pylab import *; plot()'.
991995 if self and not self .IsBeingDeleted ():
992996 super ().Destroy (* args , ** kwargs )
993- if self .toolbar is not None :
994- self .toolbar .Destroy ()
995- wxapp = wx .GetApp ()
996- if wxapp :
997- wxapp .Yield ()
997+ # self.toolbar.Destroy() should not be necessary if the close event
998+ # is allowed to propagate.
998999 return True
9991000
10001001
@@ -1043,10 +1044,9 @@ def destroy(self, *args):
10431044 _log .debug ("%s - destroy()" , type (self ))
10441045 frame = self .frame
10451046 if frame : # Else, may have been already deleted, e.g. when closing.
1046- frame .Close ()
1047- wxapp = wx .GetApp ()
1048- if wxapp :
1049- wxapp .Yield ()
1047+ # As this can be called from non-GUI thread from plt.close use
1048+ # wx.CallAfter to ensure thread safety.
1049+ wx .CallAfter (frame .Close )
10501050
10511051 def full_screen_toggle (self ):
10521052 # docstring inherited
0 commit comments