@@ -180,8 +180,7 @@ def __init__(self, ax, label, image=None,
180180 horizontalalignment = 'center' ,
181181 transform = ax .transAxes )
182182
183- self ._cnt = 0
184- self ._observers = {}
183+ self ._observers = cbook .CallbackRegistry ()
185184
186185 self .connect_event ('button_press_event' , self ._click )
187186 self .connect_event ('button_release_event' , self ._release )
@@ -196,12 +195,13 @@ def __init__(self, ax, label, image=None,
196195 @cbook .deprecated ("3.4" )
197196 @property
198197 def cnt (self ):
199- return self ._cnt
198+ # Not real, but close enough.
199+ return len (self ._observers .callbacks ['clicked' ])
200200
201201 @cbook .deprecated ("3.4" )
202202 @property
203203 def observers (self ):
204- return self ._observers
204+ return self ._observers . callbacks [ 'clicked' ]
205205
206206 def _click (self , event ):
207207 if (self .ignore (event )
@@ -219,8 +219,7 @@ def _release(self, event):
219219 if (not self .eventson
220220 or event .inaxes != self .ax ):
221221 return
222- for cid , func in self ._observers .items ():
223- func (event )
222+ self ._observers .process ('clicked' , event )
224223
225224 def _motion (self , event ):
226225 if self .ignore (event ):
@@ -237,17 +236,11 @@ def on_clicked(self, func):
237236
238237 Returns a connection id, which can be used to disconnect the callback.
239238 """
240- cid = self ._cnt
241- self ._observers [cid ] = func
242- self ._cnt += 1
243- return cid
239+ return self ._observers .connect ('clicked' , func )
244240
245241 def disconnect (self , cid ):
246242 """Remove the callback function with connection id *cid*."""
247- try :
248- del self ._observers [cid ]
249- except KeyError :
250- pass
243+ self ._observers .disconnect (cid )
251244
252245
253246class Slider (AxesWidget ):
@@ -397,20 +390,20 @@ def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None,
397390 verticalalignment = 'center' ,
398391 horizontalalignment = 'left' )
399392
400- self ._cnt = 0
401- self ._observers = {}
393+ self ._observers = cbook .CallbackRegistry ()
402394
403395 self .set_val (valinit )
404396
405397 @cbook .deprecated ("3.4" )
406398 @property
407399 def cnt (self ):
408- return self ._cnt
400+ # Not real, but close enough.
401+ return len (self ._observers .callbacks ['changed' ])
409402
410403 @cbook .deprecated ("3.4" )
411404 @property
412405 def observers (self ):
413- return self ._observers
406+ return self ._observers . callbacks [ 'changed' ]
414407
415408 def _value_in_bounds (self , val ):
416409 """Makes sure *val* is with given bounds."""
@@ -494,8 +487,7 @@ def set_val(self, val):
494487 self .val = val
495488 if not self .eventson :
496489 return
497- for cid , func in self ._observers .items ():
498- func (val )
490+ self ._observers .process ('changed' , val )
499491
500492 def on_changed (self , func ):
501493 """
@@ -513,10 +505,7 @@ def on_changed(self, func):
513505 int
514506 Connection id (which can be used to disconnect *func*)
515507 """
516- cid = self ._cnt
517- self ._observers [cid ] = func
518- self ._cnt += 1
519- return cid
508+ return self ._observers .connect ('changed' , func )
520509
521510 def disconnect (self , cid ):
522511 """
@@ -527,10 +516,7 @@ def disconnect(self, cid):
527516 cid : int
528517 Connection id of the observer to be removed
529518 """
530- try :
531- del self ._observers [cid ]
532- except KeyError :
533- pass
519+ self ._observers .disconnect (cid )
534520
535521 def reset (self ):
536522 """Reset the slider to the initial value"""
@@ -625,18 +611,18 @@ def __init__(self, ax, labels, actives=None):
625611
626612 self .connect_event ('button_press_event' , self ._clicked )
627613
628- self ._cnt = 0
629- self ._observers = {}
614+ self ._observers = cbook .CallbackRegistry ()
630615
631616 @cbook .deprecated ("3.4" )
632617 @property
633618 def cnt (self ):
634- return self ._cnt
619+ # Not real, but close enough.
620+ return len (self ._observers .callbacks ['clicked' ])
635621
636622 @cbook .deprecated ("3.4" )
637623 @property
638624 def observers (self ):
639- return self ._observers
625+ return self ._observers . callbacks [ 'clicked' ]
640626
641627 def _clicked (self , event ):
642628 if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
@@ -675,8 +661,7 @@ def set_active(self, index):
675661
676662 if not self .eventson :
677663 return
678- for cid , func in self ._observers .items ():
679- func (self .labels [index ].get_text ())
664+ self ._observers .process ('clicked' , self .labels [index ].get_text ())
680665
681666 def get_status (self ):
682667 """
@@ -690,17 +675,11 @@ def on_clicked(self, func):
690675
691676 Returns a connection id, which can be used to disconnect the callback.
692677 """
693- cid = self ._cnt
694- self ._observers [cid ] = func
695- self ._cnt += 1
696- return cid
678+ return self ._observers .connect ('clicked' , func )
697679
698680 def disconnect (self , cid ):
699681 """Remove the observer with connection id *cid*."""
700- try :
701- del self ._observers [cid ]
702- except KeyError :
703- pass
682+ self ._observers .disconnect (cid )
704683
705684
706685class TextBox (AxesWidget ):
@@ -760,9 +739,7 @@ def __init__(self, ax, label, initial='',
760739 self .DIST_FROM_LEFT , 0.5 , initial , transform = self .ax .transAxes ,
761740 verticalalignment = 'center' , horizontalalignment = 'left' )
762741
763- self ._cnt = 0
764- self ._change_observers = {}
765- self ._submit_observers = {}
742+ self ._observers = cbook .CallbackRegistry ()
766743
767744 ax .set (
768745 xlim = (0 , 1 ), ylim = (0 , 1 ), # s.t. cursor appears from first click.
@@ -788,17 +765,18 @@ def __init__(self, ax, label, initial='',
788765 @cbook .deprecated ("3.4" )
789766 @property
790767 def cnt (self ):
791- return self ._cnt
768+ # Not real, but close enough.
769+ return sum (len (d ) for d in self ._observers .callbacks .values ())
792770
793771 @cbook .deprecated ("3.4" )
794772 @property
795773 def change_observers (self ):
796- return self ._change_observers
774+ return self ._observers . callbacks [ 'change' ]
797775
798776 @cbook .deprecated ("3.4" )
799777 @property
800778 def submit_observers (self ):
801- return self ._submit_observers
779+ return self ._observers . callbacks [ 'submit' ]
802780
803781 @property
804782 def text (self ):
@@ -828,11 +806,6 @@ def _rendercursor(self):
828806
829807 self .ax .figure .canvas .draw ()
830808
831- def _notify_submit_observers (self ):
832- if self .eventson :
833- for cid , func in self ._submit_observers .items ():
834- func (self .text )
835-
836809 def _release (self , event ):
837810 if self .ignore (event ):
838811 return
@@ -871,23 +844,20 @@ def _keypress(self, event):
871844 text [self .cursor_index + 1 :])
872845 self .text_disp .set_text (text )
873846 self ._rendercursor ()
874- self ._notify_change_observers ()
875- if key == "enter" :
876- self ._notify_submit_observers ()
847+ if self .eventson :
848+ self ._observers .process ('change' , self .text )
849+ if key == "enter" :
850+ self ._observers .process ('submit' , self .text )
877851
878852 def set_val (self , val ):
879853 newval = str (val )
880854 if self .text == newval :
881855 return
882856 self .text_disp .set_text (newval )
883857 self ._rendercursor ()
884- self ._notify_change_observers ()
885- self ._notify_submit_observers ()
886-
887- def _notify_change_observers (self ):
888858 if self .eventson :
889- for cid , func in self ._change_observers . items ():
890- func ( self .text )
859+ self ._observers . process ( 'change' , self . text )
860+ self . _observers . process ( 'submit' , self .text )
891861
892862 def begin_typing (self , x ):
893863 self .capturekeystrokes = True
@@ -920,10 +890,10 @@ def stop_typing(self):
920890 self .capturekeystrokes = False
921891 self .cursor .set_visible (False )
922892 self .ax .figure .canvas .draw ()
923- if notifysubmit :
924- # Because _notify_submit_observers might throw an error in the
925- # user's code, only call it once we've already done our cleanup.
926- self ._notify_submit_observers ( )
893+ if notifysubmit and self . eventson :
894+ # Because process() might throw an error in the user's code, only
895+ # call it once we've already done our cleanup.
896+ self ._observers . process ( 'submit' , self . text )
927897
928898 def position_cursor (self , x ):
929899 # now, we have to figure out where the cursor goes.
@@ -968,10 +938,7 @@ def on_text_change(self, func):
968938
969939 A connection id is returned which can be used to disconnect.
970940 """
971- cid = self ._cnt
972- self ._change_observers [cid ] = func
973- self ._cnt += 1
974- return cid
941+ return self ._observers .connect ('change' , func )
975942
976943 def on_submit (self , func ):
977944 """
@@ -980,18 +947,11 @@ def on_submit(self, func):
980947
981948 A connection id is returned which can be used to disconnect.
982949 """
983- cid = self ._cnt
984- self ._submit_observers [cid ] = func
985- self ._cnt += 1
986- return cid
950+ return self ._observers .connect ('submit' , func )
987951
988952 def disconnect (self , cid ):
989953 """Remove the observer with connection id *cid*."""
990- for reg in [self ._change_observers , self ._submit_observers ]:
991- try :
992- del reg [cid ]
993- except KeyError :
994- pass
954+ self ._observers .disconnect (cid )
995955
996956
997957class RadioButtons (AxesWidget ):
@@ -1072,18 +1032,18 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
10721032
10731033 self .connect_event ('button_press_event' , self ._clicked )
10741034
1075- self ._cnt = 0
1076- self ._observers = {}
1035+ self ._observers = cbook .CallbackRegistry ()
10771036
10781037 @cbook .deprecated ("3.4" )
10791038 @property
10801039 def cnt (self ):
1081- return self ._cnt
1040+ # Not real, but close enough.
1041+ return len (self ._observers .callbacks ['clicked' ])
10821042
10831043 @cbook .deprecated ("3.4" )
10841044 @property
10851045 def observers (self ):
1086- return self ._observers
1046+ return self ._observers . callbacks [ 'clicked' ]
10871047
10881048 def _clicked (self , event ):
10891049 if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
@@ -1121,26 +1081,19 @@ def set_active(self, index):
11211081
11221082 if not self .eventson :
11231083 return
1124- for cid , func in self ._observers .items ():
1125- func (self .labels [index ].get_text ())
1084+ self ._observers .process ('clicked' , self .labels [index ].get_text ())
11261085
11271086 def on_clicked (self , func ):
11281087 """
11291088 Connect the callback function *func* to button click events.
11301089
11311090 Returns a connection id, which can be used to disconnect the callback.
11321091 """
1133- cid = self ._cnt
1134- self ._observers [cid ] = func
1135- self ._cnt += 1
1136- return cid
1092+ return self ._observers .connect ('clicked' , func )
11371093
11381094 def disconnect (self , cid ):
11391095 """Remove the observer with connection id *cid*."""
1140- try :
1141- del self ._observers [cid ]
1142- except KeyError :
1143- pass
1096+ self ._observers .disconnect (cid )
11441097
11451098
11461099class SubplotTool (Widget ):
0 commit comments