@@ -1037,7 +1037,84 @@ def _expand_text_props(props):
10371037 return cycler (** props )() if props else itertools .repeat ({})
10381038
10391039
1040- class CheckButtons (AxesWidget ):
1040+ class _Buttons (AxesWidget ):
1041+ """
1042+ The base class for `CheckButtons` and `RadioButtons`.
1043+
1044+ This class provides common functionality for button widgets,
1045+ such as handling click events, managing button labels, and connecting callbacks.
1046+
1047+ The class itself is private and may be changed or removed without prior warning.
1048+ However, the public API it provides to subclasses is stable and considered
1049+ public on the subclasses.
1050+ """
1051+
1052+ def _clear (self , event ):
1053+ """Internal event handler to clear the buttons."""
1054+ if self .ignore (event ) or self .canvas .is_saving ():
1055+ return
1056+ if self ._useblit and self .canvas .supports_blit :
1057+ self ._save_blit_background (self .canvas .copy_from_bbox (self .ax .bbox ))
1058+ self .ax .draw_artist (self ._buttons )
1059+
1060+ def set_label_props (self , props ):
1061+ """
1062+ Set properties of the `.Text` labels.
1063+
1064+ .. versionadded:: 3.7
1065+
1066+ Parameters
1067+ ----------
1068+ props : dict
1069+ Dictionary of `.Text` properties to be used for the labels. Same
1070+ format as label_props argument of :class:`RadioButtons` or
1071+ :class:`CheckButtons`.
1072+ """
1073+ _api .check_isinstance (dict , props = props )
1074+ props = _expand_text_props (props )
1075+ for text , prop in zip (self .labels , props ):
1076+ text .update (prop )
1077+
1078+ @_call_with_reparented_event
1079+ def _clicked (self , event ):
1080+ if self .ignore (event ) or event .button != 1 or not self .ax .contains (event )[0 ]:
1081+ return
1082+ idxs = [ # Indices of frames and of texts that contain the event.
1083+ * self ._frames .contains (event )[1 ]["ind" ],
1084+ * [i for i , text in enumerate (self .labels ) if text .contains (event )[0 ]]]
1085+ if idxs :
1086+ coords = self ._frames .get_offset_transform ().transform (
1087+ self ._frames .get_offsets ())
1088+ self .set_active ( # Closest index, only looking in idxs.
1089+ idxs [(((event .x , event .y ) - coords [idxs ]) ** 2 ).sum (- 1 ).argmin ()])
1090+
1091+ def on_clicked (self , func ):
1092+ """
1093+ Connect the callback function *func* to button click events.
1094+
1095+ Parameters
1096+ ----------
1097+ func : callable
1098+ When the button is clicked, call *func* with button label.
1099+ When all buttons are cleared, call *func* with None.
1100+ The callback func must have the signature::
1101+
1102+ def func(label: str | None) -> Any
1103+
1104+ Return values may exist, but are ignored.
1105+
1106+ Returns
1107+ -------
1108+ A connection id, which can be used to disconnect the callback.
1109+ """
1110+ return self ._observers .connect ('clicked' , func )
1111+
1112+ def disconnect (self , cid ):
1113+ """Remove the observer with connection id *cid*."""
1114+ self ._observers .disconnect (cid )
1115+
1116+
1117+ class CheckButtons (_Buttons ):
10411118 r"""
10421119 A GUI neutral set of check buttons.
10431120
@@ -1152,44 +1229,6 @@ def __init__(self, ax, labels, actives=None, *, useblit=True,
11521229
11531230 self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
11541231
1155- def _clear (self , event ):
1156- """Internal event handler to clear the buttons."""
1157- if self .ignore (event ) or self .canvas .is_saving ():
1158- return
1159- if self ._useblit and self .canvas .supports_blit :
1160- self ._save_blit_background (self .canvas .copy_from_bbox (self .ax .bbox ))
1161- self .ax .draw_artist (self ._buttons )
1162-
1163- @_call_with_reparented_event
1164- def _clicked (self , event ):
1165- if self .ignore (event ) or event .button != 1 or not self .ax .contains (event )[0 ]:
1166- return
1167- idxs = [ # Indices of frames and of texts that contain the event.
1168- * self ._frames .contains (event )[1 ]["ind" ],
1169- * [i for i , text in enumerate (self .labels ) if text .contains (event )[0 ]]]
1170- if idxs :
1171- coords = self ._frames .get_offset_transform ().transform (
1172- self ._frames .get_offsets ())
1173- self .set_active ( # Closest index, only looking in idxs.
1174- idxs [(((event .x , event .y ) - coords [idxs ]) ** 2 ).sum (- 1 ).argmin ()])
1175-
1176- def set_label_props (self , props ):
1177- """
1178- Set properties of the `.Text` labels.
1179-
1180- .. versionadded:: 3.7
1181-
1182- Parameters
1183- ----------
1184- props : dict
1185- Dictionary of `.Text` properties to be used for the labels. Same
1186- format as label_props argument of :class:`CheckButtons`.
1187- """
1188- _api .check_isinstance (dict , props = props )
1189- props = _expand_text_props (props )
1190- for text , prop in zip (self .labels , props ):
1191- text .update (prop )
1192-
11931232 def set_frame_props (self , props ):
11941233 """
11951234 Set properties of the check button frames.
@@ -1321,31 +1360,6 @@ def get_checked_labels(self):
13211360 zip (self .labels , self .get_status ())
13221361 if box_checked ]
13231362
1324- def on_clicked (self , func ):
1325- """
1326- Connect the callback function *func* to button click events.
1327-
1328- Parameters
1329- ----------
1330- func : callable
1331- When the button is clicked, call *func* with button label.
1332- When all buttons are cleared, call *func* with None.
1333- The callback func must have the signature::
1334-
1335- def func(label: str | None) -> Any
1336-
1337- Return values may exist, but are ignored.
1338-
1339- Returns
1340- -------
1341- A connection id, which can be used to disconnect the callback.
1342- """
1343- return self ._observers .connect ('clicked' , lambda text : func (text ))
1344-
1345- def disconnect (self , cid ):
1346- """Remove the observer with connection id *cid*."""
1347- self ._observers .disconnect (cid )
1348-
13491363
13501364class TextBox (AxesWidget ):
13511365 """
@@ -1612,7 +1626,7 @@ def disconnect(self, cid):
16121626 self ._observers .disconnect (cid )
16131627
16141628
1615- class RadioButtons (AxesWidget ):
1629+ class RadioButtons (_Buttons ):
16161630 """
16171631 A GUI neutral radio button.
16181632
@@ -1745,44 +1759,6 @@ def __init__(self, ax, labels, active=0, activecolor=None, *,
17451759
17461760 self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
17471761
1748- def _clear (self , event ):
1749- """Internal event handler to clear the buttons."""
1750- if self .ignore (event ) or self .canvas .is_saving ():
1751- return
1752- if self ._useblit and self .canvas .supports_blit :
1753- self ._save_blit_background (self .canvas .copy_from_bbox (self .ax .bbox ))
1754- self .ax .draw_artist (self ._buttons )
1755-
1756- @_call_with_reparented_event
1757- def _clicked (self , event ):
1758- if self .ignore (event ) or event .button != 1 or not self .ax .contains (event )[0 ]:
1759- return
1760- idxs = [ # Indices of buttons and of texts that contain the event.
1761- * self ._buttons .contains (event )[1 ]["ind" ],
1762- * [i for i , text in enumerate (self .labels ) if text .contains (event )[0 ]]]
1763- if idxs :
1764- coords = self ._buttons .get_offset_transform ().transform (
1765- self ._buttons .get_offsets ())
1766- self .set_active ( # Closest index, only looking in idxs.
1767- idxs [(((event .x , event .y ) - coords [idxs ]) ** 2 ).sum (- 1 ).argmin ()])
1768-
1769- def set_label_props (self , props ):
1770- """
1771- Set properties of the `.Text` labels.
1772-
1773- .. versionadded:: 3.7
1774-
1775- Parameters
1776- ----------
1777- props : dict
1778- Dictionary of `.Text` properties to be used for the labels. Same
1779- format as label_props argument of :class:`RadioButtons`.
1780- """
1781- _api .check_isinstance (dict , props = props )
1782- props = _expand_text_props (props )
1783- for text , prop in zip (self .labels , props ):
1784- text .update (prop )
1785-
17861762 def set_radio_props (self , props ):
17871763 """
17881764 Set properties of the `.Text` labels.
@@ -1859,31 +1835,6 @@ def clear(self):
18591835 """Reset the active button to the initially active one."""
18601836 self .set_active (self ._initial_active )
18611837
1862- def on_clicked (self , func ):
1863- """
1864- Connect the callback function *func* to button click events.
1865-
1866- Parameters
1867- ----------
1868- func : callable
1869- When the button is clicked, call *func* with button label.
1870- When all buttons are cleared, call *func* with None.
1871- The callback func must have the signature::
1872-
1873- def func(label: str | None) -> Any
1874-
1875- Return values may exist, but are ignored.
1876-
1877- Returns
1878- -------
1879- A connection id, which can be used to disconnect the callback.
1880- """
1881- return self ._observers .connect ('clicked' , func )
1882-
1883- def disconnect (self , cid ):
1884- """Remove the observer with connection id *cid*."""
1885- self ._observers .disconnect (cid )
1886-
18871838
18881839class SubplotTool (Widget ):
18891840 """
0 commit comments