@@ -971,9 +971,13 @@ def _onClose(self, event):
971
971
_log .debug ("%s - onClose()" , type (self ))
972
972
self .canvas .close_event ()
973
973
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 ()
977
981
978
982
def GetToolBar (self ):
979
983
"""Override wxFrame::GetToolBar as we don't have managed toolbar"""
@@ -990,11 +994,8 @@ def Destroy(self, *args, **kwargs):
990
994
# MPLBACKEND=wxagg python -c 'from pylab import *; plot()'.
991
995
if self and not self .IsBeingDeleted ():
992
996
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.
998
999
return True
999
1000
1000
1001
@@ -1043,10 +1044,9 @@ def destroy(self, *args):
1043
1044
_log .debug ("%s - destroy()" , type (self ))
1044
1045
frame = self .frame
1045
1046
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 )
1050
1050
1051
1051
def full_screen_toggle (self ):
1052
1052
# docstring inherited
0 commit comments