From 8aafcbf639b9d4870dbca66909231a4d9e4d3f64 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 11 Jul 2017 21:24:18 -0700 Subject: [PATCH 1/3] Move start_event_loop_default to start_event_loop. There's no benefit to the end user to having a deprecation warning in start_event_loop (which gets called e.g. by ginput) -- it's essentially just there to let the devs know that they could implement a more efficient (GUI toolkit-dependent) version. So just provide the default implementations instead and add a note that GUI toolkits may override them. flush_events doesn't need to raise by default, it can just return nothing for non-interactive backends. --- lib/matplotlib/backend_bases.py | 66 ++++++------------- lib/matplotlib/backends/backend_gtk.py | 7 -- lib/matplotlib/backends/backend_gtk3.py | 8 --- lib/matplotlib/backends/backend_tkagg.py | 8 --- lib/matplotlib/backends/backend_webagg.py | 11 ---- .../backends/backend_webagg_core.py | 11 ---- 6 files changed, 19 insertions(+), 92 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 98aca9251d4c..41239b5b5bce 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2426,55 +2426,24 @@ def new_timer(self, *args, **kwargs): return TimerBase(*args, **kwargs) def flush_events(self): - """ - Flush the GUI events for the figure. Implemented only for - backends with GUIs. - """ - raise NotImplementedError + """Flush the GUI events for the figure. - def start_event_loop(self, timeout): + GUI backends likely need to reimplement this method. """ - Start an event loop. This is used to start a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. This should not be - confused with the main GUI event loop, which is always running - and has nothing to do with this. - This is implemented only for backends with GUIs. - """ - raise NotImplementedError + def start_event_loop(self, timeout=0): + """Start a blocking event loop. - def stop_event_loop(self): - """ - Stop an event loop. This is used to stop a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. + Such an event loop is used by interactive functions, such as ginput and + waitforbuttonpress, to wait for events. This should not be confused + with the main GUI event loop, which is independent and always running. - This is implemented only for backends with GUIs. - """ - raise NotImplementedError - - def start_event_loop_default(self, timeout=0): - """ - Start an event loop. This is used to start a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. This should not be - confused with the main GUI event loop, which is always running - and has nothing to do with this. - - This function provides default event loop functionality based - on time.sleep that is meant to be used until event loop - functions for each of the GUI backends can be written. As - such, it throws a deprecated warning. + The event loop blocks until a callback function triggers + `stop_event_loop`, or *timeout* is reached. If *timeout* is negative, + never timeout. - This call blocks until a callback function triggers - stop_event_loop() or *timeout* is reached. If *timeout* is - <=0, never timeout. + Only GUI backends need to reimplement this method. """ - str = "Using default event loop until function specific" - str += " to this GUI is implemented" - warnings.warn(str, mplDeprecation) - if timeout <= 0: timeout = np.inf timestep = 0.01 @@ -2485,15 +2454,18 @@ def start_event_loop_default(self, timeout=0): time.sleep(timestep) counter += 1 - def stop_event_loop_default(self): - """ - Stop an event loop. This is used to stop a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. + def stop_event_loop(self): + """Stop the current blocking event loop. + Only GUI backends need to reimplement this method. """ self._looping = False + start_event_loop_default = cbook.deprecated( + "2.1", name="start_event_loop_default")(start_event_loop) + stop_event_loop_default = cbook.deprecated( + "2.1", name="stop_event_loop_default")(stop_event_loop) + def key_press_handler(event, canvas, toolbar=None): """ diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index 757b2b7544c0..d8d8387dca34 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -475,13 +475,6 @@ def flush_events(self): gtk.gdk.flush() gtk.gdk.threads_leave() - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ class FigureManagerGTK(FigureManagerBase): diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index a5f223a38753..df8cec6ec4a1 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -332,14 +332,6 @@ def flush_events(self): Gdk.flush() Gdk.threads_leave() - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ - class FigureManagerGTK3(FigureManagerBase): """ diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index f6190d4f369e..cb9971a00dbe 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -463,14 +463,6 @@ def new_timer(self, *args, **kwargs): def flush_events(self): self._master.update() - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ - class FigureManagerTkAgg(FigureManagerBase): """ diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index e39bf2cb2bab..a1468b39c306 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -59,17 +59,6 @@ def show(self): def new_timer(self, *args, **kwargs): return TimerTornado(*args, **kwargs) - def start_event_loop(self, timeout): - backend_bases.FigureCanvasBase.start_event_loop_default( - self, timeout) - start_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - backend_bases.FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.stop_event_loop_default.__doc__ - class WebAggApplication(tornado.web.Application): initialized = False diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index d22d00704a95..7ef40187f6fe 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -359,17 +359,6 @@ def handle_set_dpi_ratio(self, event): def send_event(self, event_type, **kwargs): self.manager._send_event(event_type, **kwargs) - def start_event_loop(self, timeout): - backend_bases.FigureCanvasBase.start_event_loop_default( - self, timeout) - start_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - backend_bases.FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.stop_event_loop_default.__doc__ - _JQUERY_ICON_CLASSES = { 'home': 'ui-icon ui-icon-home', From 95dc08fd1604eb30090342598717f4be58a7284a Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 11 Jul 2017 21:33:27 -0700 Subject: [PATCH 2/3] Let pause always run the event loop. The default `start_event_loop` is not as efficient as it could be for non-interactive backends (it runs a busy loop) but if you really care you should just call time.sleep in that case. Meanwhile, this avoids the need for third-party interactive backends to register themselves into rcsetup.interactive_bk in order to be correctly pause()able. --- lib/matplotlib/pyplot.py | 42 +++++++++++++++------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 5c78047db80b..79ee0f2deccc 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -75,8 +75,7 @@ def _backend_selection(): loop, and if not switches to a compatible one. """ backend = rcParams['backend'] - if not rcParams['backend_fallback'] or \ - backend not in _interactive_bk: + if not rcParams['backend_fallback'] or backend not in _interactive_bk: return is_agg_backend = rcParams['backend'].endswith('Agg') if 'wx' in sys.modules and not backend in ('WX', 'WXAgg'): @@ -275,33 +274,24 @@ def pause(interval): """ Pause for *interval* seconds. - If there is an active figure it will be updated and displayed, - and the GUI event loop will run during the pause. + If there is an active figure, it will be updated and displayed before the + pause, and the GUI event loop (if any) will run during the pause. - If there is no active figure, or if a non-interactive backend - is in use, this executes time.sleep(interval). - - This can be used for crude animation. For more complex - animation, see :mod:`matplotlib.animation`. - - This function is experimental; its behavior may be changed - or extended in a future release. + This can be used for crude animation. For more complex animation, see + :mod:`matplotlib.animation`. + This function is experimental; its behavior may be changed or extended in a + future release. """ - backend = rcParams['backend'] - if backend in _interactive_bk: - figManager = _pylab_helpers.Gcf.get_active() - if figManager is not None: - canvas = figManager.canvas - if canvas.figure.stale: - canvas.draw_idle() - show(block=False) - canvas.start_event_loop(interval) - return - - # No on-screen figure is active, so sleep() is all we need. - import time - time.sleep(interval) + manager = _pylab_helpers.Gcf.get_active() + if manager is not None: + canvas = manager.canvas + if canvas.figure.stale: + canvas.draw_idle() + show(block=False) + canvas.start_event_loop(interval) + else: + time.sleep(interval) @docstring.copy_dedent(matplotlib.rc) From e1484e2e4a99d181ee0d0a3a48937f30ece72b57 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 6 Aug 2017 16:26:33 -0400 Subject: [PATCH 3/3] DOC: Change text start/stop_event_loop docstrings --- lib/matplotlib/backend_bases.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 41239b5b5bce..bbc4e02b3776 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2428,21 +2428,24 @@ def new_timer(self, *args, **kwargs): def flush_events(self): """Flush the GUI events for the figure. - GUI backends likely need to reimplement this method. + Interactive backends need to reimplement this method. """ def start_event_loop(self, timeout=0): """Start a blocking event loop. - Such an event loop is used by interactive functions, such as ginput and - waitforbuttonpress, to wait for events. This should not be confused - with the main GUI event loop, which is independent and always running. + Such an event loop is used by interactive functions, such as `ginput` + and `waitforbuttonpress`, to wait for events. The event loop blocks until a callback function triggers - `stop_event_loop`, or *timeout* is reached. If *timeout* is negative, - never timeout. + `stop_event_loop`, or *timeout* is reached. - Only GUI backends need to reimplement this method. + If *timeout* is negative, never timeout. + + Only interactive backends need to reimplement this method and it relies + on `flush_events` being properly implemented. + + Interactive backends should implement this in a more native way. """ if timeout <= 0: timeout = np.inf @@ -2457,7 +2460,8 @@ def start_event_loop(self, timeout=0): def stop_event_loop(self): """Stop the current blocking event loop. - Only GUI backends need to reimplement this method. + Interactive backends need to reimplement this to match + `start_event_loop` """ self._looping = False pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy