Revision: 8250 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8250&view=rev Author: ryanmay Date: 2010-04-20 19:40:12 +0000 (Tue, 20 Apr 2010)
Log Message: ----------- Add base support and API for creating backend-independant timers, implemented using the GUI toolkit's timer support. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backend_bases.py Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-04-20 19:01:53 UTC (rev 8249) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-04-20 19:40:12 UTC (rev 8250) @@ -861,6 +861,137 @@ return None return Path.hatch(self._hatch, density) + +class TimerBase(object): + ''' + A base class for providing timer events, useful for things animations. + Backends need to implement a few specific methods in order to use their + own timing mechanisms so that the timer events are integrated into their + event loops. + + Mandatory functions that must be implemented: + * _timer_start: Contains backend-specific code for starting the timer + * _timer_stop: Contains backend-specific code for stopping the timer + + Optional overrides: + * _timer_set_single_shot: Code for setting the timer to single shot + operating mode, if supported by the timer object. If not, the Timer + class itself will store the flag and the _on_timer method should + be overridden to support such behavior. + * _timer_set_interval: Code for setting the interval on the timer, if + there is a method for doing so on the timer object. + * _on_timer: This is the internal function that any timer object should + call, which will handle the task of running all callbacks that have + been set. + + 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. + ''' + def __init__(self): + #Initialize empty callbacks list and setup default settings + self.callbacks = [] + self._single = False + self._interval = 1000 + + # 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() + + def start(self, interval=None): + ''' + Start the timer object. `interval` is optional and will be used + to reset the timer interval first if provided. + ''' + if interval is not None: + self.set_interval(interval) + self._timer_start() + + def stop(self): + ''' + Stop the timer. + ''' + self._timer_stop() + + def _timer_start(self): + #TODO: Could we potentially make a generic version through + #the use of Threads? + raise NotImplementedError('Needs to be implemented by subclass.') + + def _timer_stop(self): + #TODO: Could we potentially make a generic version through + #the use of Threads? + raise NotImplementedError('Needs to be implemented by subclass.') + + def _get_interval(self): + return self._interval + + def _set_interval(self, interval): + self._interval = interval + self._timer_set_interval() + + interval = property(_get_interval, _set_interval) + + def _get_single_shot(self): + return self._single + + def _set_single_shot(self, ss=True): + self._single = ss + self._timer_set_single_shot() + + single_shot = property(_get_single_shot, _set_single_shot) + + def add_callback(self, func, *args): + ''' + Register `func` to be called by timer when the event fires. Any + additional arguments provided will be passed to `func`. + ''' + self.callbacks.append((func, args)) + + def remove_callback(self, func, *args): + ''' + Remove `func` from list of callbacks. `args` is optional and used + to distinguish between copies of the same function registered to be + called with different arguments. + ''' + if args: + self.callbacks.remove((func, args)) + else: + funcs = [c[0] for c in self.callbacks] + if func in funcs: + self.callbacks.pop(funcs.index(func)) + + def _timer_set_interval(self): + 'Used to set interval on underlying timer object.' + pass + + def _timer_set_single_shot(self): + 'Used to set single shot on underlying timer object.' + pass + + def _on_timer(self): + ''' + Runs all function that have been registered as callbacks. Functions + can return False if they should not be called any more. If there + are no callbacks, the timer is automatically stopped. + ''' + for func,args in self.callbacks: + ret = func(args) + if ret == False: + self.callbacks.remove((func,args)) + + if len(self.callbacks) == 0: + self.stop() + + class Event: """ A matplotlib event. Attach additional attributes as defined in @@ -1455,7 +1586,6 @@ event = IdleEvent(s, self, guiEvent=guiEvent) self.callbacks.process(s, event) - def draw(self, *args, **kwargs): """ Render the :class:`~matplotlib.figure.Figure` @@ -1799,6 +1929,14 @@ """ return self.callbacks.disconnect(cid) + def new_timer(self): + """ + 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. + """ + return TimerBase() + def flush_events(self): """ Flush the GUI events for the figure. Implemented only for This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ _______________________________________________ Matplotlib-checkins mailing list Matplotlib-checkins@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins