From fefa2be3dda6de2316e31ab0152344f476b7517b Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sun, 7 Apr 2013 12:14:59 +0900 Subject: [PATCH 1/8] Making the Tkagg Timer independent of the canvas --- lib/matplotlib/backends/backend_tkagg.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index 5de248ab7657..1171dd012a74 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -123,18 +123,18 @@ class TimerTk(TimerBase): upon timer events. This list can be manipulated directly, or the functions add_callback and remove_callback can be used. ''' - def __init__(self, parent, *args, **kwargs): + def __init__(self, *args, **kwargs): TimerBase.__init__(self, *args, **kwargs) - self.parent = parent self._timer = None + self._tcl = Tk.Tcl() def _timer_start(self): self._timer_stop() - self._timer = self.parent.after(self._interval, self._on_timer) + self._timer = self._tcl.after(self._interval, self._on_timer) def _timer_stop(self): if self._timer is not None: - self.parent.after_cancel(self._timer) + self._tcl.after_cancel(self._timer) self._timer = None def _on_timer(self): @@ -143,7 +143,7 @@ def _on_timer(self): # Tk after() is only a single shot, so we need to add code here to # reset the timer if we're not operating in single shot mode. if not self._single and len(self.callbacks) > 0: - self._timer = self.parent.after(self._interval, self._on_timer) + self._timer = self._tcl.after(self._interval, self._on_timer) else: self._timer = None @@ -493,7 +493,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerTk(self._tkcanvas, *args, **kwargs) + return TimerTk(*args, **kwargs) def flush_events(self): self._master.update() From fdf55d71526f182efb3390bae9f1d9133b55aba8 Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sun, 7 Apr 2013 13:36:51 +0900 Subject: [PATCH 2/8] Making the WX timer independent of the canvas --- lib/matplotlib/backends/backend_wx.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index f9cd226f1001..42fee59cdc09 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -165,7 +165,7 @@ def raise_msg_to_str(msg): return msg -class TimerWx(TimerBase): +class TimerWx(TimerBase, wx.Timer): ''' Subclass of :class:`backend_bases.TimerBase` that uses WxTimer events. @@ -180,23 +180,13 @@ class TimerWx(TimerBase): ''' def __init__(self, parent, *args, **kwargs): TimerBase.__init__(self, *args, **kwargs) - - # Create a new timer and connect the timer event to our handler. - # For WX, the events have to use a widget for binding. - self.parent = parent - self._timer = wx.Timer(self.parent, wx.NewId()) - self.parent.Bind(wx.EVT_TIMER, self._on_timer, self._timer) - - # Unbinding causes Wx to stop for some reason. Disabling for now. -# def __del__(self): -# TimerBase.__del__(self) -# self.parent.Bind(wx.EVT_TIMER, None, self._timer) + wx.Timer.__init__(self) def _timer_start(self): - self._timer.Start(self._interval, self._single) + self.Start(self._interval, self._single) def _timer_stop(self): - self._timer.Stop() + self.Stop() def _timer_set_interval(self): self._timer_start() @@ -204,8 +194,8 @@ def _timer_set_interval(self): def _timer_set_single_shot(self): self._timer.start() - def _on_timer(self, *args): - TimerBase._on_timer(self) + def Notify(self): + self._on_timer() class RendererWx(RendererBase): From af374e64f146c87a4ca3fb59f873eaeb95ebeaa0 Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sun, 7 Apr 2013 13:39:34 +0900 Subject: [PATCH 3/8] parent is not needed any more --- lib/matplotlib/backends/backend_wx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index 42fee59cdc09..76019a280592 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -178,7 +178,7 @@ class TimerWx(TimerBase, wx.Timer): upon timer events. This list can be manipulated directly, or the functions add_callback and remove_callback can be used. ''' - def __init__(self, parent, *args, **kwargs): + def __init__(self, *args, **kwargs): TimerBase.__init__(self, *args, **kwargs) wx.Timer.__init__(self) @@ -1010,7 +1010,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerWx(self, *args, **kwargs) + return TimerWx(*args, **kwargs) def flush_events(self): wx.Yield() From 13faf523e69642c17140a018fb97716e251833b4 Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sun, 7 Apr 2013 18:08:32 +0900 Subject: [PATCH 4/8] Putting the Timer code in a separate submodule (events) --- examples/event_handling/timers.py | 3 ++- lib/matplotlib/animation.py | 4 ++- lib/matplotlib/backends/backend_gtk.py | 2 +- lib/matplotlib/backends/backend_gtk3.py | 4 +-- lib/matplotlib/backends/backend_gtk3agg.py | 1 + lib/matplotlib/backends/backend_gtkagg.py | 2 +- lib/matplotlib/backends/backend_macosx.py | 4 +-- lib/matplotlib/backends/backend_qt4.py | 4 +-- lib/matplotlib/backends/backend_qt4agg.py | 2 +- lib/matplotlib/backends/backend_tkagg.py | 4 +-- lib/matplotlib/backends/backend_webagg.py | 4 +-- lib/matplotlib/backends/backend_wx.py | 4 +-- lib/matplotlib/backends/backend_wxagg.py | 2 +- lib/matplotlib/events.py | 29 ++++++++++++++++++++++ 14 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 lib/matplotlib/events.py diff --git a/examples/event_handling/timers.py b/examples/event_handling/timers.py index 2541f11aae3e..f5ca20e3d035 100644 --- a/examples/event_handling/timers.py +++ b/examples/event_handling/timers.py @@ -1,6 +1,7 @@ # Simple example of using general timer objects. This is used to update # the time placed in the title of the figure. import matplotlib.pyplot as plt +from matplotlib import events import numpy as np from datetime import datetime @@ -16,7 +17,7 @@ def update_title(axes): # Create a new timer object. Set the interval 500 milliseconds (1000 is default) # and tell the timer what function should be called. -timer = fig.canvas.new_timer(interval=100) +timer = events.Timer(interval=100) timer.add_callback(update_title, ax) timer.start() diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index de2d17a30eae..ac75802fde02 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -24,6 +24,8 @@ from matplotlib.compat import subprocess from matplotlib import verbose from matplotlib import rcParams +from matplotlib import events + # Other potential writing methods: # * http://pymedia.org/ @@ -845,7 +847,7 @@ def __init__(self, fig, interval=200, repeat_delay=None, repeat=True, # If we're not given an event source, create a new timer. This permits # sharing timers between animation objects for syncing animations. if event_source is None: - event_source = fig.canvas.new_timer() + event_source = events.Timer() event_source.interval = self._interval Animation.__init__(self, fig, event_source=event_source, diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index 3b30686b86a4..e819fb0702be 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -102,7 +102,7 @@ def new_figure_manager_given_figure(num, figure): return manager -class TimerGTK(TimerBase): +class Timer(TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses GTK for timer events. diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index be12f4e68c38..002274b19c04 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -57,7 +57,7 @@ def mainloop(self): show = Show() -class TimerGTK3(TimerBase): +class Timer(TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses GTK3 for timer events. @@ -324,7 +324,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerGTK3(*args, **kwargs) + return Timer(*args, **kwargs) def flush_events(self): Gdk.threads_enter() diff --git a/lib/matplotlib/backends/backend_gtk3agg.py b/lib/matplotlib/backends/backend_gtk3agg.py index ada6da4d5d50..18719119b3dc 100644 --- a/lib/matplotlib/backends/backend_gtk3agg.py +++ b/lib/matplotlib/backends/backend_gtk3agg.py @@ -104,3 +104,4 @@ def new_figure_manager_given_figure(num, figure): FigureManager = FigureManagerGTK3Agg show = backend_gtk3.show +Timer = backend_gtk3.Timer diff --git a/lib/matplotlib/backends/backend_gtkagg.py b/lib/matplotlib/backends/backend_gtkagg.py index cdd0bbae8723..dc96d9c883eb 100644 --- a/lib/matplotlib/backends/backend_gtkagg.py +++ b/lib/matplotlib/backends/backend_gtkagg.py @@ -10,7 +10,7 @@ from matplotlib.backends.backend_gtk import gtk, FigureManagerGTK, FigureCanvasGTK,\ show, draw_if_interactive,\ error_msg_gtk, NavigationToolbar, PIXELS_PER_INCH, backend_version, \ - NavigationToolbar2GTK + NavigationToolbar2GTK, Timer from matplotlib.backends._gtkagg import agg_to_gtk_drawable diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index ed17506e4a79..777d7246fd8e 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -245,7 +245,7 @@ def new_figure_manager_given_figure(num, figure): return manager -class TimerMac(_macosx.Timer, TimerBase): +class Timer(_macosx.Timer, TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses CoreFoundation run loops for timer events. @@ -343,7 +343,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerMac(*args, **kwargs) + return Timer(*args, **kwargs) class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 3caad0bf90c1..31b7dc2bf5f3 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -85,7 +85,7 @@ def new_figure_manager_given_figure(num, figure): return manager -class TimerQT(TimerBase): +class Timer(TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses Qt4 timer events. @@ -345,7 +345,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerQT(*args, **kwargs) + return Timer(*args, **kwargs) def flush_events(self): QtGui.qApp.processEvents() diff --git a/lib/matplotlib/backends/backend_qt4agg.py b/lib/matplotlib/backends/backend_qt4agg.py index 659f4a8ddae1..d88514a5d10d 100644 --- a/lib/matplotlib/backends/backend_qt4agg.py +++ b/lib/matplotlib/backends/backend_qt4agg.py @@ -12,7 +12,7 @@ from backend_agg import FigureCanvasAgg from backend_qt4 import QtCore, QtGui, FigureManagerQT, FigureCanvasQT,\ show, draw_if_interactive, backend_version, \ - NavigationToolbar2QT + NavigationToolbar2QT, Timer DEBUG = False diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index 1171dd012a74..f49f3e4aa7d8 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -110,7 +110,7 @@ def new_figure_manager_given_figure(num, figure): return figManager -class TimerTk(TimerBase): +class Timer(TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses Tk's timer events. @@ -493,7 +493,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerTk(*args, **kwargs) + return Timer(*args, **kwargs) def flush_events(self): self._master.update() diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index 19702c0bc2da..ee13b32ae5d7 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -76,7 +76,7 @@ def new_figure_manager_given_figure(num, figure): return manager -class TimerTornado(backend_bases.TimerBase): +class Timer(backend_bases.TimerBase): def _timer_start(self): self._timer_stop() if self._single: @@ -258,7 +258,7 @@ def send_event(self, event_type, **kwargs): self.manager.send_event(event_type, **kwargs) def new_timer(self, *args, **kwargs): - return TimerTornado(*args, **kwargs) + return Timer(*args, **kwargs) def start_event_loop(self, timeout): backend_bases.FigureCanvasBase.start_event_loop_default( diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index 76019a280592..9e0f13a7d055 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -165,7 +165,7 @@ def raise_msg_to_str(msg): return msg -class TimerWx(TimerBase, wx.Timer): +class Timer(wx.Timer, TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses WxTimer events. @@ -1010,7 +1010,7 @@ def new_timer(self, *args, **kwargs): Sequence of (func, args, kwargs) where func(*args, **kwargs) will be executed by the timer every *interval*. """ - return TimerWx(*args, **kwargs) + return Timer(*args, **kwargs) def flush_events(self): wx.Yield() diff --git a/lib/matplotlib/backends/backend_wxagg.py b/lib/matplotlib/backends/backend_wxagg.py index 5b301a045f04..b1edf14b781e 100644 --- a/lib/matplotlib/backends/backend_wxagg.py +++ b/lib/matplotlib/backends/backend_wxagg.py @@ -23,7 +23,7 @@ import backend_wx # already uses wxversion.ensureMinimal('2.8') from backend_wx import FigureManager, FigureManagerWx, FigureCanvasWx, \ FigureFrameWx, DEBUG_MSG, NavigationToolbar2Wx, error_msg_wx, \ - draw_if_interactive, show, Toolbar, backend_version + draw_if_interactive, show, Toolbar, Timer, backend_version import wx class FigureFrameWxAgg(FigureFrameWx): diff --git a/lib/matplotlib/events.py b/lib/matplotlib/events.py new file mode 100644 index 000000000000..929e4cc95477 --- /dev/null +++ b/lib/matplotlib/events.py @@ -0,0 +1,29 @@ +import matplotlib + +def _initialize(): + backend = matplotlib.get_backend() + # Import the requested backend into a generic module object + if backend.startswith('module://'): + backend_name = backend[9:] + else: + backend_name = 'backend_'+backend + backend_name = backend_name.lower() # until we banish mixed case + backend_name = 'matplotlib.backends.%s'%backend_name.lower() + backend_module = __import__(backend_name, globals(), locals(), [backend_name]) + return backend_module + +backend = _initialize() + +class Timer(backend.Timer): + ''' + Subclass of :class:`backend_bases.TimerBase` that uses backend-specific timer events. + + Attributes: + * interval: The time between timer events in milliseconds. Default + is 1000 ms. + * callbacks: Stores list of (func, args) tuples that will be called + upon timer events. This list can be manipulated directly, or the + functions add_callback and remove_callback can be used. + ''' + +del backend, _initialize From 9eea83c788bdfa080a32a035ea4c3a9bbcf0d8e2 Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sat, 13 Apr 2013 08:28:23 +0900 Subject: [PATCH 5/8] Keep the docstring in only one place --- lib/matplotlib/backend_bases.py | 3 --- lib/matplotlib/backends/backend_gtk.py | 14 ++-------- lib/matplotlib/backends/backend_gtk3.py | 14 ++-------- lib/matplotlib/backends/backend_macosx.py | 14 +--------- lib/matplotlib/backends/backend_qt4.py | 32 +++++++---------------- lib/matplotlib/backends/backend_tkagg.py | 14 ++-------- lib/matplotlib/backends/backend_webagg.py | 2 ++ lib/matplotlib/backends/backend_wx.py | 14 ++-------- lib/matplotlib/events.py | 14 +--------- 9 files changed, 22 insertions(+), 99 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 52752aa99825..a0719f2892ee 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -1049,9 +1049,6 @@ def __init__(self, interval=None, callbacks=None): self._single = False - # Default attribute for holding the GUI-specific timer object - self._timer = None - def __del__(self): 'Need to stop timer and possibly disconnect timer.' self._timer_stop() diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index e819fb0702be..d11313104736 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -103,18 +103,8 @@ def new_figure_manager_given_figure(num, figure): class Timer(TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses GTK for timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' + __doc__ = TimerBase.__doc__ + def _timer_start(self): # Need to stop it, otherwise we potentially leak a timer id that will # never be stopped. diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 002274b19c04..da432274fbe2 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -58,18 +58,8 @@ def mainloop(self): class Timer(TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses GTK3 for timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' + __doc__ = TimerBase.__doc__ + def _timer_start(self): # Need to stop it, otherwise we potentially leak a timer id that will # never be stopped. diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index 777d7246fd8e..e8e2236f786b 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -246,19 +246,7 @@ def new_figure_manager_given_figure(num, figure): class Timer(_macosx.Timer, TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses CoreFoundation - run loops for timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' + __doc__ = TimerBase.__doc__ # completely implemented at the C-level (in _macosx.Timer) diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 31b7dc2bf5f3..a5a587317bc6 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -85,50 +85,38 @@ def new_figure_manager_given_figure(num, figure): return manager -class Timer(TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses Qt4 timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' +class Timer(TimerBase, QtCore.QTimer): + __doc__ = TimerBase.__doc__ + def __init__(self, *args, **kwargs): TimerBase.__init__(self, *args, **kwargs) # Create a new timer and connect the timeout() signal to the # _on_timer method. - self._timer = QtCore.QTimer() - QtCore.QObject.connect(self._timer, QtCore.SIGNAL('timeout()'), - self._on_timer) + QtCore.QTimer.__init__(self) + self.timeout.connect(self._on_timer) self._timer_set_interval() def __del__(self): # Probably not necessary in practice, but is good behavior to disconnect try: TimerBase.__del__(self) - QtCore.QObject.disconnect(self._timer, - QtCore.SIGNAL('timeout()'), self._on_timer) + self.timeout.disconnect(self._on_timer) except RuntimeError: # Timer C++ object already deleted pass def _timer_set_single_shot(self): - self._timer.setSingleShot(self._single) + self.setSingleShot(self._single) def _timer_set_interval(self): - self._timer.setInterval(self._interval) + self.setInterval(self._interval) def _timer_start(self): - self._timer.start() + QtCore.QTimer.start(self) def _timer_stop(self): - self._timer.stop() + QtCore.QTimer.stop(self) class FigureCanvasQT( QtGui.QWidget, FigureCanvasBase ): diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index f49f3e4aa7d8..c7921e6eb160 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -111,18 +111,8 @@ def new_figure_manager_given_figure(num, figure): class Timer(TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses Tk's timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' + __doc__ = TimerBase.__doc__ + def __init__(self, *args, **kwargs): TimerBase.__init__(self, *args, **kwargs) self._timer = None diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index ee13b32ae5d7..48bb20f7de6b 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -77,6 +77,8 @@ def new_figure_manager_given_figure(num, figure): class Timer(backend_bases.TimerBase): + __doc__ = backend_bases.TimerBase.__doc__ + def _timer_start(self): self._timer_stop() if self._single: diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index 9e0f13a7d055..eeb52e54926b 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -166,18 +166,8 @@ def raise_msg_to_str(msg): class Timer(wx.Timer, TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses WxTimer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' + __doc__ = TimerBase.__doc__ + def __init__(self, *args, **kwargs): TimerBase.__init__(self, *args, **kwargs) wx.Timer.__init__(self) diff --git a/lib/matplotlib/events.py b/lib/matplotlib/events.py index 929e4cc95477..ef27cd5adcc8 100644 --- a/lib/matplotlib/events.py +++ b/lib/matplotlib/events.py @@ -13,17 +13,5 @@ def _initialize(): return backend_module backend = _initialize() - -class Timer(backend.Timer): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses backend-specific timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' - +Timer = backend.Timer del backend, _initialize From a055253c3f369f630165afb9e3048e0dd6629ebe Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sat, 13 Apr 2013 10:41:51 +0900 Subject: [PATCH 6/8] make sure the backend base timer is always available --- lib/matplotlib/backends/backend_gtk.py | 4 ++++ lib/matplotlib/events.py | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index d11313104736..8261ecbdc405 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -105,6 +105,10 @@ def new_figure_manager_given_figure(num, figure): class Timer(TimerBase): __doc__ = TimerBase.__doc__ + def __init__(self, *args, **kwargs): + TimerBase.__init__(self, *args, **kwargs) + self._timer = None + def _timer_start(self): # Need to stop it, otherwise we potentially leak a timer id that will # never be stopped. diff --git a/lib/matplotlib/events.py b/lib/matplotlib/events.py index ef27cd5adcc8..2da8452708b8 100644 --- a/lib/matplotlib/events.py +++ b/lib/matplotlib/events.py @@ -13,5 +13,8 @@ def _initialize(): return backend_module backend = _initialize() -Timer = backend.Timer +try: + Timer = backend.Timer +except AttributeError: + from matplotlib.backend_bases import TimerBase as Timer del backend, _initialize From 9a3fbf44a0dd5ec0d39ef672ce76c4ac0249cf19 Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Sat, 13 Apr 2013 10:51:03 +0900 Subject: [PATCH 7/8] provide _timer for gtk3 --- lib/matplotlib/backends/backend_gtk3.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index da432274fbe2..c254d267c074 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -60,6 +60,10 @@ def mainloop(self): class Timer(TimerBase): __doc__ = TimerBase.__doc__ + def __init__(self, *args, **kwargs): + TimerBase.__init__(self, *args, **kwargs) + self._timer = None + def _timer_start(self): # Need to stop it, otherwise we potentially leak a timer id that will # never be stopped. From 6bcf7e6aec0e32a4bfe610ad6ea1ede56e9ca357 Mon Sep 17 00:00:00 2001 From: Michiel de Hoon Date: Tue, 16 Apr 2013 06:57:06 +0900 Subject: [PATCH 8/8] Removing the now obsolete new_timer method --- lib/matplotlib/backend_bases.py | 17 ----------------- lib/matplotlib/backends/backend_gtk.py | 16 ---------------- lib/matplotlib/backends/backend_gtk3.py | 16 ---------------- lib/matplotlib/backends/backend_macosx.py | 16 ---------------- lib/matplotlib/backends/backend_qt4.py | 16 ---------------- lib/matplotlib/backends/backend_tkagg.py | 16 ---------------- lib/matplotlib/backends/backend_webagg.py | 3 --- lib/matplotlib/backends/backend_wx.py | 16 ---------------- 8 files changed, 116 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index a0719f2892ee..f2c79178e3a8 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2255,23 +2255,6 @@ def mpl_disconnect(self, cid): """ return self.callbacks.disconnect(cid) - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of - :class:`backend_bases.Timer`. This is useful for getting periodic - events through the backend's native event loop. Implemented only for - backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return TimerBase(*args, **kwargs) - def flush_events(self): """ Flush the GUI events for the figure. Implemented only for diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index 8261ecbdc405..0412c3d18463 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -481,22 +481,6 @@ def save_callback(buf, data=None): else: raise ValueError("filename must be a path or a file-like object") - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return TimerGTK(*args, **kwargs) - def flush_events(self): gtk.gdk.threads_enter() while gtk.events_pending(): diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index c254d267c074..6467473f8e3a 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -304,22 +304,6 @@ def idle_draw(*args): if self._idle_draw_id == 0: self._idle_draw_id = GObject.idle_add(idle_draw) - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return Timer(*args, **kwargs) - def flush_events(self): Gdk.threads_enter() while Gtk.events_pending(): diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index e8e2236f786b..b313d473bef7 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -317,22 +317,6 @@ def print_tiff(self, filename, *args, **kwargs): def print_gif(self, filename, *args, **kwargs): self._print_bitmap(filename, *args, **kwargs) - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return Timer(*args, **kwargs) - class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): """ diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index a5a587317bc6..afffa4efbd15 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -319,22 +319,6 @@ def _get_key( self, event ): return key - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return Timer(*args, **kwargs) - def flush_events(self): QtGui.qApp.processEvents() diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index c7921e6eb160..39e9d8116b98 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -469,22 +469,6 @@ def key_release(self, event): key = self._get_key(event) FigureCanvasBase.key_release_event(self, key, guiEvent=event) - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return Timer(*args, **kwargs) - def flush_events(self): self._master.update() diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index 48bb20f7de6b..baa3a80632de 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -259,9 +259,6 @@ def handle_event(self, event): def send_event(self, event_type, **kwargs): self.manager.send_event(event_type, **kwargs) - def new_timer(self, *args, **kwargs): - return Timer(*args, **kwargs) - def start_event_loop(self, timeout): backend_bases.FigureCanvasBase.start_event_loop_default( self, timeout) diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index eeb52e54926b..c597bf1e0146 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -986,22 +986,6 @@ def draw(self, drawDC=None): self._isDrawn = True self.gui_repaint(drawDC=drawDC) - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return Timer(*args, **kwargs) - def flush_events(self): wx.Yield()