Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 34c3305

Browse files
committed
[3015013] use atexit in _pylab_helpers to ensure orderly shutdown.
It closes all windows; in the case of Tk, this calls the root.destroy() function, which should prevent the PyEval_RestoreThread error on Win. See http://mail.python.org/pipermail/python-bugs-list/2002-November/014207.html This changeset also refactors the close() functionality into three Gcf methods, fixing a bug (or inconsistency) in which calling close with a figure number failed to call mpl_disconnect. svn path=/trunk/matplotlib/; revision=8424
1 parent 16b98a5 commit 34c3305

4 files changed

Lines changed: 34 additions & 20 deletions

File tree

lib/matplotlib/_pylab_helpers.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44

55
import sys, gc
66

7+
import atexit
8+
import traceback
9+
10+
711
def error_msg(msg):
8-
print >>sys.stderr, msgs
12+
print >>sys.stderr, msg
913

1014
class Gcf(object):
1115
"""
@@ -34,10 +38,10 @@ def get_fig_manager(num):
3438
If figure manager *num* exists, make it the active
3539
figure and return the manager; otherwise return *None*.
3640
"""
37-
figManager = Gcf.figs.get(num, None)
38-
if figManager is not None:
39-
Gcf.set_active(figManager)
40-
return figManager
41+
manager = Gcf.figs.get(num, None)
42+
if manager is not None:
43+
Gcf.set_active(manager)
44+
return manager
4145

4246
@staticmethod
4347
def destroy(num):
@@ -48,21 +52,35 @@ def destroy(num):
4852
window "destroy" and "delete" events.
4953
"""
5054
if not Gcf.has_fignum(num): return
51-
figManager = Gcf.figs[num]
55+
manager = Gcf.figs[num]
56+
manager.canvas.mpl_disconnect(manager._cidgcf)
5257

5358
# There must be a good reason for the following careful
5459
# rebuilding of the activeQue; what is it?
5560
oldQue = Gcf._activeQue[:]
5661
Gcf._activeQue = []
5762
for f in oldQue:
58-
if f != figManager:
63+
if f != manager:
5964
Gcf._activeQue.append(f)
6065

6166
del Gcf.figs[num]
6267
#print len(Gcf.figs.keys()), len(Gcf._activeQue)
63-
figManager.destroy()
68+
manager.destroy()
6469
gc.collect()
6570

71+
@staticmethod
72+
def destroy_fig(fig):
73+
"*fig* is a Figure instance"
74+
for manager in Gcf.figs.values():
75+
if manager.canvas.figure == fig:
76+
Gcf.destroy(manager.num)
77+
78+
@staticmethod
79+
def destroy_all():
80+
for manager in Gcf.figs.values():
81+
Gcf.destroy(manager.num)
82+
83+
6684
@staticmethod
6785
def has_fignum(num):
6886
"""
@@ -105,3 +123,7 @@ def set_active(manager):
105123
Gcf._activeQue.append(manager)
106124
Gcf.figs[manager.num] = manager
107125

126+
atexit.register(Gcf.destroy_all)
127+
128+
129+

lib/matplotlib/backends/backend_gtk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ def destroy(self, *args):
551551
self.canvas.destroy()
552552
if self.toolbar:
553553
self.toolbar.destroy()
554-
self.__dict__.clear()
554+
self.__dict__.clear() #Is this needed? Other backends don't have it.
555555

556556
if Gcf.get_num_fig_managers()==0 and \
557557
not matplotlib.is_interactive() and \

lib/matplotlib/backends/backend_tkagg.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,9 +491,7 @@ def destroy(self, *args):
491491
if self.window is not None:
492492
#self.toolbar.destroy()
493493
self.window.destroy()
494-
495-
pass
496-
self.window = None
494+
self.window = None
497495

498496
def set_window_title(self, title):
499497
self.window.wm_title(title)

lib/matplotlib/pyplot.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -315,21 +315,15 @@ def close(*args):
315315
figManager = _pylab_helpers.Gcf.get_active()
316316
if figManager is None: return
317317
else:
318-
figManager.canvas.mpl_disconnect(figManager._cidgcf)
319318
_pylab_helpers.Gcf.destroy(figManager.num)
320319
elif len(args)==1:
321320
arg = args[0]
322321
if arg=='all':
323-
for manager in _pylab_helpers.Gcf.get_all_fig_managers():
324-
manager.canvas.mpl_disconnect(manager._cidgcf)
325-
_pylab_helpers.Gcf.destroy(manager.num)
322+
_pylab_helpers.Gcf.destroy_all()
326323
elif isinstance(arg, int):
327324
_pylab_helpers.Gcf.destroy(arg)
328325
elif isinstance(arg, Figure):
329-
for manager in _pylab_helpers.Gcf.get_all_fig_managers():
330-
if manager.canvas.figure==arg:
331-
manager.canvas.mpl_disconnect(manager._cidgcf)
332-
_pylab_helpers.Gcf.destroy(manager.num)
326+
_pylab_helpers.Gcf.destroy_fig(arg)
333327
else:
334328
raise TypeError('Unrecognized argument type %s to close'%type(arg))
335329
else:

0 commit comments

Comments
 (0)