@@ -113,12 +113,19 @@ class AxesWidget(Widget):
113113 The parent figure canvas for the widget.
114114 active : bool
115115 If False, the widget does not respond to events.
116+ useblit : bool
117+ Whether usage of blitting is desired. The actual usage of
118+ blitting also depends on the canvas supporting it.
119+
120+ Once set, this is read-only, as some widgets currently still
121+ depend on the state statically. They still query _useblit.
116122 """
117123
118- def __init__ (self , ax ):
124+ def __init__ (self , ax , useblit = False ):
119125 self .ax = ax
120126 self ._cids = []
121127 self ._blit_background_id = None
128+ self ._useblit = useblit
122129
123130 def __del__ (self ):
124131 if self ._blit_background_id is not None :
@@ -151,6 +158,16 @@ def _set_cursor(self, cursor):
151158 """Update the canvas cursor."""
152159 self .ax .get_figure (root = True ).canvas .set_cursor (cursor )
153160
161+ def _should_use_blit (self ):
162+ """
163+ Return whether blitting should be used.
164+
165+ All blitting-related code must be guarded by this because
166+ not all canvases support blit and canvases may be swapped
167+ out during the lifetime of the widget.
168+ """
169+ return self ._useblit and self .canvas .supports_blit
170+
154171 def _save_blit_background (self , background ):
155172 """
156173 Save a blit background.
@@ -239,7 +256,7 @@ def __init__(self, ax, label, image=None,
239256
240257 .. versionadded:: 3.7
241258 """
242- super ().__init__ (ax )
259+ super ().__init__ (ax , useblit = useblit )
243260
244261 if image is not None :
245262 ax .imshow (image )
@@ -248,8 +265,6 @@ def __init__(self, ax, label, image=None,
248265 horizontalalignment = 'center' ,
249266 transform = ax .transAxes )
250267
251- self ._useblit = useblit
252-
253268 self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
254269
255270 self .connect_event ('button_press_event' , self ._click )
@@ -285,7 +300,7 @@ def _motion(self, event):
285300 if not colors .same_color (c , self .ax .get_facecolor ()):
286301 self .ax .set_facecolor (c )
287302 if self .drawon :
288- if self ._useblit and self . canvas . supports_blit :
303+ if self ._should_use_blit () :
289304 self .ax .draw_artist (self .ax )
290305 self .canvas .blit (self .ax .bbox )
291306 else :
@@ -1096,7 +1111,7 @@ def __init__(self, ax, labels, actives=None, *, useblit=True,
10961111
10971112 .. versionadded:: 3.7
10981113 """
1099- super ().__init__ (ax )
1114+ super ().__init__ (ax , useblit = useblit )
11001115
11011116 _api .check_isinstance ((dict , None ), label_props = label_props ,
11021117 frame_props = frame_props , check_props = check_props )
@@ -1108,8 +1123,6 @@ def __init__(self, ax, labels, actives=None, *, useblit=True,
11081123 if actives is None :
11091124 actives = [False ] * len (labels )
11101125
1111- self ._useblit = useblit
1112-
11131126 ys = np .linspace (1 , 0 , len (labels )+ 2 )[1 :- 1 ]
11141127
11151128 label_props = _expand_text_props (label_props )
@@ -1158,7 +1171,7 @@ def _clear(self, event):
11581171 """Internal event handler to clear the buttons."""
11591172 if self .ignore (event ) or self .canvas .is_saving ():
11601173 return
1161- if self ._useblit and self . canvas . supports_blit :
1174+ if self ._should_use_blit () :
11621175 self ._save_blit_background (self .canvas .copy_from_bbox (self .ax .bbox ))
11631176 self .ax .draw_artist (self ._checks )
11641177
@@ -1264,7 +1277,7 @@ def set_active(self, index, state=None):
12641277 self ._checks .set_facecolor (facecolors )
12651278
12661279 if self .drawon :
1267- if self ._useblit and self . canvas . supports_blit :
1280+ if self ._should_use_blit () :
12681281 background = self ._load_blit_background ()
12691282 if background is not None :
12701283 self .canvas .restore_region (background )
@@ -1678,7 +1691,7 @@ def __init__(self, ax, labels, active=0, activecolor=None, *,
16781691
16791692 .. versionadded:: 3.7
16801693 """
1681- super ().__init__ (ax )
1694+ super ().__init__ (ax , useblit = useblit )
16821695
16831696 _api .check_isinstance ((dict , None ), label_props = label_props ,
16841697 radio_props = radio_props )
@@ -1705,8 +1718,6 @@ def __init__(self, ax, labels, active=0, activecolor=None, *,
17051718
17061719 ys = np .linspace (1 , 0 , len (labels ) + 2 )[1 :- 1 ]
17071720
1708- self ._useblit = useblit
1709-
17101721 label_props = _expand_text_props (label_props )
17111722 self .labels = [
17121723 ax .text (0.25 , y , label , transform = ax .transAxes ,
@@ -1751,7 +1762,7 @@ def _clear(self, event):
17511762 """Internal event handler to clear the buttons."""
17521763 if self .ignore (event ) or self .canvas .is_saving ():
17531764 return
1754- if self ._useblit and self . canvas . supports_blit :
1765+ if self ._should_use_blit () :
17551766 self ._save_blit_background (self .canvas .copy_from_bbox (self .ax .bbox ))
17561767 self .ax .draw_artist (self ._buttons )
17571768
@@ -1845,7 +1856,7 @@ def set_active(self, index):
18451856 self ._buttons .set_facecolor (button_facecolors )
18461857
18471858 if self .drawon :
1848- if self ._useblit and self . canvas . supports_blit :
1859+ if self ._should_use_blit () :
18491860 background = self ._load_blit_background ()
18501861 if background is not None :
18511862 self .canvas .restore_region (background )
@@ -1989,7 +2000,7 @@ class Cursor(AxesWidget):
19892000 """
19902001 def __init__ (self , ax , * , horizOn = True , vertOn = True , useblit = False ,
19912002 ** lineprops ):
1992- super ().__init__ (ax )
2003+ super ().__init__ (ax , useblit = useblit )
19932004
19942005 self .connect_event ('motion_notify_event' , self .onmove )
19952006 self .connect_event ('draw_event' , self .clear )
@@ -2010,7 +2021,7 @@ def clear(self, event):
20102021 """Internal event handler to clear the cursor."""
20112022 if self .ignore (event ) or self .canvas .is_saving ():
20122023 return
2013- if self .useblit :
2024+ if self ._should_use_blit () :
20142025 self ._save_blit_background (self .canvas .copy_from_bbox (self .ax .bbox ))
20152026
20162027 @_call_with_reparented_event
@@ -2035,7 +2046,7 @@ def onmove(self, event):
20352046 if not (self .visible and (self .vertOn or self .horizOn )):
20362047 return
20372048 # Redraw.
2038- if self .useblit :
2049+ if self ._should_use_blit () :
20392050 background = self ._load_blit_background ()
20402051 if background is not None :
20412052 self .canvas .restore_region (background )
@@ -2205,14 +2216,13 @@ class _SelectorWidget(AxesWidget):
22052216
22062217 def __init__ (self , ax , onselect = None , useblit = False , button = None ,
22072218 state_modifier_keys = None , use_data_coordinates = False ):
2208- super ().__init__ (ax )
2219+ super ().__init__ (ax , useblit = useblit )
22092220
22102221 self ._visible = True
22112222 if onselect is None :
22122223 self .onselect = lambda * args : None
22132224 else :
22142225 self .onselect = onselect
2215- self ._useblit = useblit
22162226 self .connect_default_events ()
22172227
22182228 self ._state_modifier_keys = dict (move = ' ' , clear = 'escape' ,
@@ -2239,7 +2249,7 @@ def __init__(self, ax, onselect=None, useblit=False, button=None,
22392249 @property
22402250 def useblit (self ):
22412251 """Return whether blitting is used (requested and supported by canvas)."""
2242- return self ._useblit and self . canvas . supports_blit
2252+ return self ._should_use_blit ()
22432253
22442254 def set_active (self , active ):
22452255 super ().set_active (active )
@@ -2262,7 +2272,7 @@ def update_background(self, event):
22622272 """Force an update of the background."""
22632273 # If you add a call to `ignore` here, you'll want to check edge case:
22642274 # `release` can call a draw event even when `ignore` is True.
2265- if not self .useblit :
2275+ if not self ._should_use_blit () :
22662276 return
22672277 if self .canvas .is_saving ():
22682278 return # saving does not use blitting
@@ -2323,11 +2333,11 @@ def ignore(self, event):
23232333 event .button != self ._eventpress .button )
23242334
23252335 def update (self ):
2326- """Draw using blit() or draw_idle(), depending on ``self.useblit`` ."""
2336+ """Draw using blit() or draw_idle(), depending on blitting support ."""
23272337 if (not self .ax .get_visible () or
23282338 self .ax .get_figure (root = True )._get_renderer () is None ):
23292339 return
2330- if self .useblit :
2340+ if self ._should_use_blit () :
23312341 background = self ._load_blit_background ()
23322342 if background is not None :
23332343 self .canvas .restore_region (background )
@@ -2500,7 +2510,7 @@ def set_props(self, **props):
25002510 artist = self ._selection_artist
25012511 props = cbook .normalize_kwargs (props , artist )
25022512 artist .set (** props )
2503- if self .useblit :
2513+ if self ._should_use_blit () :
25042514 self .update ()
25052515
25062516 def set_handle_props (self , ** handle_props ):
@@ -2516,7 +2526,7 @@ def set_handle_props(self, **handle_props):
25162526 handle_props = cbook .normalize_kwargs (handle_props , artist )
25172527 for handle in self ._handles_artists :
25182528 handle .set (** handle_props )
2519- if self .useblit :
2529+ if self ._should_use_blit () :
25202530 self .update ()
25212531 self ._handle_props .update (handle_props )
25222532
0 commit comments