@@ -1220,11 +1220,16 @@ class Event:
1220
1220
guiEvent
1221
1221
The GUI event that triggered the Matplotlib event.
1222
1222
"""
1223
+
1223
1224
def __init__ (self , name , canvas , guiEvent = None ):
1224
1225
self .name = name
1225
1226
self .canvas = canvas
1226
1227
self .guiEvent = guiEvent
1227
1228
1229
+ def _process (self ):
1230
+ """Generate an event with name ``self.name`` on ``self.canvas``."""
1231
+ self .canvas .callbacks .process (self .name , self )
1232
+
1228
1233
1229
1234
class DrawEvent (Event ):
1230
1235
"""
@@ -1267,14 +1272,28 @@ class ResizeEvent(Event):
1267
1272
height : int
1268
1273
Height of the canvas in pixels.
1269
1274
"""
1275
+
1270
1276
def __init__ (self , name , canvas ):
1271
1277
super ().__init__ (name , canvas )
1272
1278
self .width , self .height = canvas .get_width_height ()
1273
1279
1280
+ def _process (self ):
1281
+ super ()._process ()
1282
+ self .canvas .draw_idle ()
1283
+
1274
1284
1275
1285
class CloseEvent (Event ):
1276
1286
"""An event triggered by a figure being closed."""
1277
1287
1288
+ def _process (self ):
1289
+ try :
1290
+ super ()._process ()
1291
+ except (AttributeError , TypeError ):
1292
+ pass
1293
+ # Suppress AttributeError/TypeError that occur when the python
1294
+ # session is being killed. It may be that a better solution would
1295
+ # be a mechanism to disconnect all callbacks upon shutdown.
1296
+
1278
1297
1279
1298
class LocationEvent (Event ):
1280
1299
"""
@@ -1294,7 +1313,7 @@ class LocationEvent(Event):
1294
1313
is not over an Axes.
1295
1314
"""
1296
1315
1297
- lastevent = None # the last event that was triggered before this one
1316
+ lastevent = None # The last event processed so far.
1298
1317
1299
1318
def __init__ (self , name , canvas , x , y , guiEvent = None ):
1300
1319
super ().__init__ (name , canvas , guiEvent = guiEvent )
@@ -1308,7 +1327,6 @@ def __init__(self, name, canvas, x, y, guiEvent=None):
1308
1327
1309
1328
if x is None or y is None :
1310
1329
# cannot check if event was in Axes if no (x, y) info
1311
- self ._update_enter_leave ()
1312
1330
return
1313
1331
1314
1332
if self .canvas .mouse_grabber is None :
@@ -1326,33 +1344,21 @@ def __init__(self, name, canvas, x, y, guiEvent=None):
1326
1344
self .xdata = xdata
1327
1345
self .ydata = ydata
1328
1346
1329
- self ._update_enter_leave ()
1330
-
1331
- def _update_enter_leave (self ):
1332
- """Process the figure/axes enter leave events."""
1333
- if LocationEvent .lastevent is not None :
1334
- last = LocationEvent .lastevent
1335
- if last .inaxes != self .inaxes :
1336
- # process Axes enter/leave events
1347
+ def _process (self ):
1348
+ last = LocationEvent .lastevent
1349
+ last_axes = last .inaxes if last is not None else None
1350
+ if last_axes != self .inaxes :
1351
+ if last_axes is not None :
1337
1352
try :
1338
- if last .inaxes is not None :
1339
- last .canvas .callbacks .process ('axes_leave_event' , last )
1353
+ last .canvas .callbacks .process ("axes_leave_event" , last )
1340
1354
except Exception :
1355
+ # The last canvas may already have been torn down.
1341
1356
pass
1342
- # See ticket 2901582.
1343
- # I think this is a valid exception to the rule
1344
- # against catching all exceptions; if anything goes
1345
- # wrong, we simply want to move on and process the
1346
- # current event.
1347
- if self .inaxes is not None :
1348
- self .canvas .callbacks .process ('axes_enter_event' , self )
1349
-
1350
- else :
1351
- # process a figure enter event
1352
1357
if self .inaxes is not None :
1353
- self .canvas .callbacks .process ('axes_enter_event' , self )
1354
-
1355
- LocationEvent .lastevent = self
1358
+ self .canvas .callbacks .process ("axes_enter_event" , self )
1359
+ LocationEvent .lastevent = (
1360
+ None if self .name == "figure_leave_event" else self )
1361
+ super ()._process ()
1356
1362
1357
1363
1358
1364
class MouseButton (IntEnum ):
@@ -1375,11 +1381,15 @@ class MouseEvent(LocationEvent):
1375
1381
----------
1376
1382
button : None or `MouseButton` or {'up', 'down'}
1377
1383
The button pressed. 'up' and 'down' are used for scroll events.
1384
+
1378
1385
Note that LEFT and RIGHT actually refer to the "primary" and
1379
1386
"secondary" buttons, i.e. if the user inverts their left and right
1380
1387
buttons ("left-handed setting") then the LEFT button will be the one
1381
1388
physically on the right.
1382
1389
1390
+ If this is unset, *name* is "scroll_event", and *step* is nonzero, then
1391
+ this will be set to "up" or "down" depending on the sign of *step*.
1392
+
1383
1393
key : None or str
1384
1394
The key pressed when the mouse event triggered, e.g. 'shift'.
1385
1395
See `KeyEvent`.
@@ -1413,6 +1423,11 @@ def __init__(self, name, canvas, x, y, button=None, key=None,
1413
1423
step = 0 , dblclick = False , guiEvent = None ):
1414
1424
if button in MouseButton .__members__ .values ():
1415
1425
button = MouseButton (button )
1426
+ if name == "scroll_event" and button is None :
1427
+ if step > 0 :
1428
+ button = "up"
1429
+ elif step < 0 :
1430
+ button = "down"
1416
1431
self .button = button
1417
1432
self .key = key
1418
1433
self .step = step
@@ -1422,6 +1437,17 @@ def __init__(self, name, canvas, x, y, button=None, key=None,
1422
1437
# 'axes_enter_event', which requires a fully initialized event.
1423
1438
super ().__init__ (name , canvas , x , y , guiEvent = guiEvent )
1424
1439
1440
+ def _process (self ):
1441
+ if self .name == "button_press_event" :
1442
+ self .canvas ._button = self .button
1443
+ elif self .name == "button_release_event" :
1444
+ self .canvas ._button = None
1445
+ elif self .name == "motion_notify_event" and self .button is None :
1446
+ self .button = self .canvas ._button
1447
+ if self .key is None :
1448
+ self .key = self .canvas ._key
1449
+ super ()._process ()
1450
+
1425
1451
def __str__ (self ):
1426
1452
return (f"{ self .name } : "
1427
1453
f"xy=({ self .x } , { self .y } ) xydata=({ self .xdata } , { self .ydata } ) "
@@ -1467,8 +1493,11 @@ def on_pick(event):
1467
1493
1468
1494
cid = fig.canvas.mpl_connect('pick_event', on_pick)
1469
1495
"""
1496
+
1470
1497
def __init__ (self , name , canvas , mouseevent , artist ,
1471
1498
guiEvent = None , ** kwargs ):
1499
+ if guiEvent is None :
1500
+ guiEvent = mouseevent .guiEvent
1472
1501
super ().__init__ (name , canvas , guiEvent )
1473
1502
self .mouseevent = mouseevent
1474
1503
self .artist = artist
@@ -1506,11 +1535,19 @@ def on_key(event):
1506
1535
1507
1536
cid = fig.canvas.mpl_connect('key_press_event', on_key)
1508
1537
"""
1538
+
1509
1539
def __init__ (self , name , canvas , key , x = 0 , y = 0 , guiEvent = None ):
1510
1540
self .key = key
1511
1541
# super-init deferred to the end: callback errors if called before
1512
1542
super ().__init__ (name , canvas , x , y , guiEvent = guiEvent )
1513
1543
1544
+ def _process (self ):
1545
+ if self .name == "key_press_event" :
1546
+ self .canvas ._key = self .key
1547
+ elif self .name == "key_release_event" :
1548
+ self .canvas ._key = None
1549
+ super ()._process ()
1550
+
1514
1551
1515
1552
def _get_renderer (figure , print_method = None ):
1516
1553
"""
@@ -1720,12 +1757,16 @@ def resize(self, w, h):
1720
1757
_api .warn_deprecated ("3.6" , name = "resize" , obj_type = "method" ,
1721
1758
alternative = "FigureManagerBase.resize" )
1722
1759
1760
+ @_api .deprecated ("3.6" , alternative = (
1761
+ "callbacks.process('draw_event', DrawEvent(...))" ))
1723
1762
def draw_event (self , renderer ):
1724
1763
"""Pass a `DrawEvent` to all functions connected to ``draw_event``."""
1725
1764
s = 'draw_event'
1726
1765
event = DrawEvent (s , self , renderer )
1727
1766
self .callbacks .process (s , event )
1728
1767
1768
+ @_api .deprecated ("3.6" , alternative = (
1769
+ "callbacks.process('resize_event', ResizeEvent(...))" ))
1729
1770
def resize_event (self ):
1730
1771
"""
1731
1772
Pass a `ResizeEvent` to all functions connected to ``resize_event``.
@@ -1735,6 +1776,8 @@ def resize_event(self):
1735
1776
self .callbacks .process (s , event )
1736
1777
self .draw_idle ()
1737
1778
1779
+ @_api .deprecated ("3.6" , alternative = (
1780
+ "callbacks.process('close_event', CloseEvent(...))" ))
1738
1781
def close_event (self , guiEvent = None ):
1739
1782
"""
1740
1783
Pass a `CloseEvent` to all functions connected to ``close_event``.
@@ -1751,6 +1794,8 @@ def close_event(self, guiEvent=None):
1751
1794
# AttributeError occurs on OSX with qt4agg upon exiting
1752
1795
# with an open window; 'callbacks' attribute no longer exists.
1753
1796
1797
+ @_api .deprecated ("3.6" , alternative = (
1798
+ "callbacks.process('key_press_event', KeyEvent(...))" ))
1754
1799
def key_press_event (self , key , guiEvent = None ):
1755
1800
"""
1756
1801
Pass a `KeyEvent` to all functions connected to ``key_press_event``.
@@ -1761,6 +1806,8 @@ def key_press_event(self, key, guiEvent=None):
1761
1806
s , self , key , self ._lastx , self ._lasty , guiEvent = guiEvent )
1762
1807
self .callbacks .process (s , event )
1763
1808
1809
+ @_api .deprecated ("3.6" , alternative = (
1810
+ "callbacks.process('key_release_event', KeyEvent(...))" ))
1764
1811
def key_release_event (self , key , guiEvent = None ):
1765
1812
"""
1766
1813
Pass a `KeyEvent` to all functions connected to ``key_release_event``.
@@ -1771,6 +1818,8 @@ def key_release_event(self, key, guiEvent=None):
1771
1818
self .callbacks .process (s , event )
1772
1819
self ._key = None
1773
1820
1821
+ @_api .deprecated ("3.6" , alternative = (
1822
+ "callbacks.process('pick_event', PickEvent(...))" ))
1774
1823
def pick_event (self , mouseevent , artist , ** kwargs ):
1775
1824
"""
1776
1825
Callback processing for pick events.
@@ -1787,6 +1836,8 @@ def pick_event(self, mouseevent, artist, **kwargs):
1787
1836
** kwargs )
1788
1837
self .callbacks .process (s , event )
1789
1838
1839
+ @_api .deprecated ("3.6" , alternative = (
1840
+ "callbacks.process('scroll_event', MouseEvent(...))" ))
1790
1841
def scroll_event (self , x , y , step , guiEvent = None ):
1791
1842
"""
1792
1843
Callback processing for scroll events.
@@ -1807,6 +1858,8 @@ def scroll_event(self, x, y, step, guiEvent=None):
1807
1858
step = step , guiEvent = guiEvent )
1808
1859
self .callbacks .process (s , mouseevent )
1809
1860
1861
+ @_api .deprecated ("3.6" , alternative = (
1862
+ "callbacks.process('button_press_event', MouseEvent(...))" ))
1810
1863
def button_press_event (self , x , y , button , dblclick = False , guiEvent = None ):
1811
1864
"""
1812
1865
Callback processing for mouse button press events.
@@ -1824,6 +1877,8 @@ def button_press_event(self, x, y, button, dblclick=False, guiEvent=None):
1824
1877
dblclick = dblclick , guiEvent = guiEvent )
1825
1878
self .callbacks .process (s , mouseevent )
1826
1879
1880
+ @_api .deprecated ("3.6" , alternative = (
1881
+ "callbacks.process('button_release_event', MouseEvent(...))" ))
1827
1882
def button_release_event (self , x , y , button , guiEvent = None ):
1828
1883
"""
1829
1884
Callback processing for mouse button release events.
@@ -1848,6 +1903,9 @@ def button_release_event(self, x, y, button, guiEvent=None):
1848
1903
self .callbacks .process (s , event )
1849
1904
self ._button = None
1850
1905
1906
+ # Also remove _lastx, _lasty when this goes away.
1907
+ @_api .deprecated ("3.6" , alternative = (
1908
+ "callbacks.process('motion_notify_event', MouseEvent(...))" ))
1851
1909
def motion_notify_event (self , x , y , guiEvent = None ):
1852
1910
"""
1853
1911
Callback processing for mouse movement events.
@@ -1873,6 +1931,8 @@ def motion_notify_event(self, x, y, guiEvent=None):
1873
1931
guiEvent = guiEvent )
1874
1932
self .callbacks .process (s , event )
1875
1933
1934
+ @_api .deprecated ("3.6" , alternative = (
1935
+ "callbacks.process('leave_notify_event', LocationEvent(...))" ))
1876
1936
def leave_notify_event (self , guiEvent = None ):
1877
1937
"""
1878
1938
Callback processing for the mouse cursor leaving the canvas.
@@ -1889,6 +1949,8 @@ def leave_notify_event(self, guiEvent=None):
1889
1949
LocationEvent .lastevent = None
1890
1950
self ._lastx , self ._lasty = None , None
1891
1951
1952
+ @_api .deprecated ("3.6" , alternative = (
1953
+ "callbacks.process('enter_notify_event', LocationEvent(...))" ))
1892
1954
def enter_notify_event (self , guiEvent = None , xy = None ):
1893
1955
"""
1894
1956
Callback processing for the mouse cursor entering the canvas.
0 commit comments