Skip to content

Commit 43efa34

Browse files
committed
Merge pull request #717 from jdh2358/key-press-handler
expose key press handler
2 parents b765d87 + b3e43e6 commit 43efa34

File tree

5 files changed

+194
-93
lines changed

5 files changed

+194
-93
lines changed

doc/users/navigation_toolbar.rst

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ The ``Save`` button
7676
``svg`` and ``pdf``.
7777

7878

79+
.. _key-event-handling:
80+
7981
Navigation Keyboard Shortcuts
8082
-----------------------------
8183

examples/user_interfaces/embedding_in_gtk2.py

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#from matplotlib.backends.backend_gtk import NavigationToolbar2GTK as NavigationToolbar
1818
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
1919

20+
# implement the default mpl key bindings
21+
from matplotlib.backend_bases import key_press_handler
2022

2123
win = gtk.Window()
2224
win.connect("destroy", lambda x: gtk.main_quit())
@@ -40,5 +42,11 @@
4042
vbox.pack_start(toolbar, False, False)
4143

4244

45+
def on_key_event(event):
46+
print('you pressed %s'%event.key)
47+
key_press_handler(event, canvas, toolbar)
48+
49+
canvas.mpl_connect('key_press_event', on_key_event)
50+
4351
win.show_all()
4452
gtk.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import sys
2+
import numpy as np
3+
from matplotlib.figure import Figure
4+
from matplotlib.backend_bases import FigureManagerBase, key_press_handler
5+
from PyQt4.QtCore import *
6+
from PyQt4.QtGui import *
7+
8+
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
9+
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
10+
11+
12+
class AppForm(QMainWindow):
13+
def __init__(self, parent=None):
14+
QMainWindow.__init__(self, parent)
15+
#self.x, self.y = self.get_data()
16+
self.data = self.get_data2()
17+
self.create_main_frame()
18+
self.on_draw()
19+
20+
def create_main_frame(self):
21+
self.main_frame = QWidget()
22+
23+
self.fig = Figure((5.0, 4.0), dpi=100)
24+
self.canvas = FigureCanvas(self.fig)
25+
self.canvas.setParent(self.main_frame)
26+
self.canvas.setFocusPolicy( Qt.StrongFocus )
27+
self.canvas.setFocus()
28+
29+
self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)
30+
31+
self.canvas.mpl_connect('key_press_event', self.on_key_press)
32+
33+
vbox = QVBoxLayout()
34+
vbox.addWidget(self.canvas) # the matplotlib canvas
35+
vbox.addWidget(self.mpl_toolbar)
36+
self.main_frame.setLayout(vbox)
37+
self.setCentralWidget(self.main_frame)
38+
39+
def get_data2(self):
40+
return np.arange(20).reshape([4,5]).copy()
41+
42+
def on_draw(self):
43+
self.fig.clear()
44+
self.axes = self.fig.add_subplot(111)
45+
#self.axes.plot(self.x, self.y, 'ro')
46+
self.axes.imshow(self.data, interpolation='nearest')
47+
#self.axes.plot([1,2,3])
48+
self.canvas.draw()
49+
50+
def on_key_press(self, event):
51+
print 'you pressed', event.key
52+
# implement the default mpl key press events described at
53+
# http://matplotlib.sourceforge.net/users/navigation_toolbar.html#navigation-keyboard-shortcuts
54+
key_press_handler(event, self.canvas, self.mpl_toolbar)
55+
56+
def main():
57+
app = QApplication(sys.argv)
58+
form = AppForm()
59+
form.show()
60+
app.exec_()
61+
62+
if __name__ == "__main__":
63+
main()

examples/user_interfaces/embedding_in_tk.py

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
from numpy import arange, sin, pi
77
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
8+
# implement the default mpl key bindings
9+
from matplotlib.backend_bases import key_press_handler
10+
11+
812
from matplotlib.figure import Figure
913

1014
import sys
@@ -34,6 +38,12 @@
3438
toolbar.update()
3539
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
3640

41+
def on_key_event(event):
42+
print('you pressed %s'%event.key)
43+
key_press_handler(event, canvas, toolbar)
44+
45+
canvas.mpl_connect('key_press_event', on_key_event)
46+
3747
def _quit():
3848
root.quit() # stops mainloop
3949
root.destroy() # this is necessary on Windows to prevent

lib/matplotlib/backend_bases.py

+111-93
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,7 @@ def __init__(self, figure):
14361436
self.button_pick_id = self.mpl_connect('button_press_event',self.pick)
14371437
self.scroll_pick_id = self.mpl_connect('scroll_event',self.pick)
14381438
self.mouse_grabber = None # the axes currently grabbing mouse
1439-
1439+
self.toolbar = None # NavigationToolbar2 will set me
14401440
if False:
14411441
## highlight the artists that are hit
14421442
self.mpl_connect('motion_notify_event',self.onHilite)
@@ -2213,6 +2213,110 @@ def stop_event_loop_default(self):
22132213
self._looping = False
22142214

22152215

2216+
def key_press_handler(event, canvas, toolbar=None):
2217+
"""
2218+
Implement the default mpl key bindings for the canvas and toolbar
2219+
described at :ref:`key-event-handling`
2220+
2221+
*event*
2222+
a :class:`KeyEvent` instance
2223+
*canvas*
2224+
a :class:`FigureCanvasBase` instance
2225+
*toolbar*
2226+
a :class:`NavigationToolbar2` instance
2227+
2228+
"""
2229+
# these bindings happen whether you are over an axes or not
2230+
#if event.key == 'q':
2231+
# self.destroy() # how cruel to have to destroy oneself!
2232+
# return
2233+
2234+
if event.key is None:
2235+
return
2236+
2237+
# Load key-mappings from your matplotlibrc file.
2238+
fullscreen_keys = rcParams['keymap.fullscreen']
2239+
home_keys = rcParams['keymap.home']
2240+
back_keys = rcParams['keymap.back']
2241+
forward_keys = rcParams['keymap.forward']
2242+
pan_keys = rcParams['keymap.pan']
2243+
zoom_keys = rcParams['keymap.zoom']
2244+
save_keys = rcParams['keymap.save']
2245+
grid_keys = rcParams['keymap.grid']
2246+
toggle_yscale_keys = rcParams['keymap.yscale']
2247+
toggle_xscale_keys = rcParams['keymap.xscale']
2248+
all = rcParams['keymap.all_axes']
2249+
2250+
# toggle fullscreen mode (default key 'f')
2251+
if event.key in fullscreen_keys:
2252+
self.full_screen_toggle()
2253+
2254+
if toolbar is not None:
2255+
# home or reset mnemonic (default key 'h', 'home' and 'r')
2256+
if event.key in home_keys:
2257+
toolbar.home()
2258+
# forward / backward keys to enable left handed quick navigation
2259+
# (default key for backward: 'left', 'backspace' and 'c')
2260+
elif event.key in back_keys:
2261+
toolbar.back()
2262+
# (default key for forward: 'right' and 'v')
2263+
elif event.key in forward_keys:
2264+
toolbar.forward()
2265+
# pan mnemonic (default key 'p')
2266+
elif event.key in pan_keys:
2267+
toolbar.pan()
2268+
# zoom mnemonic (default key 'o')
2269+
elif event.key in zoom_keys:
2270+
toolbar.zoom()
2271+
# saving current figure (default key 's')
2272+
elif event.key in save_keys:
2273+
toolbar.save_figure()
2274+
2275+
if event.inaxes is None:
2276+
return
2277+
2278+
# the mouse has to be over an axes to trigger these
2279+
# switching on/off a grid in current axes (default key 'g')
2280+
if event.key in grid_keys:
2281+
event.inaxes.grid()
2282+
canvas.draw()
2283+
# toggle scaling of y-axes between 'log and 'linear' (default key 'l')
2284+
elif event.key in toggle_yscale_keys:
2285+
ax = event.inaxes
2286+
scale = ax.get_yscale()
2287+
if scale == 'log':
2288+
ax.set_yscale('linear')
2289+
ax.figure.canvas.draw()
2290+
elif scale == 'linear':
2291+
ax.set_yscale('log')
2292+
ax.figure.canvas.draw()
2293+
# toggle scaling of x-axes between 'log and 'linear' (default key 'k')
2294+
elif event.key in toggle_xscale_keys:
2295+
ax = event.inaxes
2296+
scalex = ax.get_xscale()
2297+
if scalex == 'log':
2298+
ax.set_xscale('linear')
2299+
ax.figure.canvas.draw()
2300+
elif scalex == 'linear':
2301+
ax.set_xscale('log')
2302+
ax.figure.canvas.draw()
2303+
2304+
elif (event.key.isdigit() and event.key!='0') or event.key in all:
2305+
# keys in list 'all' enables all axes (default key 'a'),
2306+
# otherwise if key is a number only enable this particular axes
2307+
# if it was the axes, where the event was raised
2308+
if not (event.key in all):
2309+
n = int(event.key)-1
2310+
for i, a in enumerate(canvas.figure.get_axes()):
2311+
# consider axes, in which the event was raised
2312+
# FIXME: Why only this axes?
2313+
if event.x is not None and event.y is not None \
2314+
and a.in_axes(event):
2315+
if event.key in all:
2316+
a.set_navigate(True)
2317+
else:
2318+
a.set_navigate(i==n)
2319+
22162320

22172321
class FigureManagerBase:
22182322
"""
@@ -2224,7 +2328,7 @@ class FigureManagerBase:
22242328
A :class:`FigureCanvasBase` instance
22252329
22262330
*num*
2227-
The figure nuamber
2331+
The figure number
22282332
"""
22292333
def __init__(self, canvas, num):
22302334
self.canvas = canvas
@@ -2244,97 +2348,11 @@ def resize(self, w, h):
22442348
pass
22452349

22462350
def key_press(self, event):
2247-
2248-
# these bindings happen whether you are over an axes or not
2249-
#if event.key == 'q':
2250-
# self.destroy() # how cruel to have to destroy oneself!
2251-
# return
2252-
2253-
if event.key is None:
2254-
return
2255-
2256-
# Load key-mappings from your matplotlibrc file.
2257-
fullscreen_keys = rcParams['keymap.fullscreen']
2258-
home_keys = rcParams['keymap.home']
2259-
back_keys = rcParams['keymap.back']
2260-
forward_keys = rcParams['keymap.forward']
2261-
pan_keys = rcParams['keymap.pan']
2262-
zoom_keys = rcParams['keymap.zoom']
2263-
save_keys = rcParams['keymap.save']
2264-
grid_keys = rcParams['keymap.grid']
2265-
toggle_yscale_keys = rcParams['keymap.yscale']
2266-
toggle_xscale_keys = rcParams['keymap.xscale']
2267-
all = rcParams['keymap.all_axes']
2268-
2269-
# toggle fullscreen mode (default key 'f')
2270-
if event.key in fullscreen_keys:
2271-
self.full_screen_toggle()
2272-
2273-
# home or reset mnemonic (default key 'h', 'home' and 'r')
2274-
elif event.key in home_keys:
2275-
self.canvas.toolbar.home()
2276-
# forward / backward keys to enable left handed quick navigation
2277-
# (default key for backward: 'left', 'backspace' and 'c')
2278-
elif event.key in back_keys:
2279-
self.canvas.toolbar.back()
2280-
# (default key for forward: 'right' and 'v')
2281-
elif event.key in forward_keys:
2282-
self.canvas.toolbar.forward()
2283-
# pan mnemonic (default key 'p')
2284-
elif event.key in pan_keys:
2285-
self.canvas.toolbar.pan()
2286-
# zoom mnemonic (default key 'o')
2287-
elif event.key in zoom_keys:
2288-
self.canvas.toolbar.zoom()
2289-
# saving current figure (default key 's')
2290-
elif event.key in save_keys:
2291-
self.canvas.toolbar.save_figure()
2292-
2293-
if event.inaxes is None:
2294-
return
2295-
2296-
# the mouse has to be over an axes to trigger these
2297-
# switching on/off a grid in current axes (default key 'g')
2298-
if event.key in grid_keys:
2299-
event.inaxes.grid()
2300-
self.canvas.draw()
2301-
# toggle scaling of y-axes between 'log and 'linear' (default key 'l')
2302-
elif event.key in toggle_yscale_keys:
2303-
ax = event.inaxes
2304-
scale = ax.get_yscale()
2305-
if scale == 'log':
2306-
ax.set_yscale('linear')
2307-
ax.figure.canvas.draw()
2308-
elif scale == 'linear':
2309-
ax.set_yscale('log')
2310-
ax.figure.canvas.draw()
2311-
# toggle scaling of x-axes between 'log and 'linear' (default key 'k')
2312-
elif event.key in toggle_xscale_keys:
2313-
ax = event.inaxes
2314-
scalex = ax.get_xscale()
2315-
if scalex == 'log':
2316-
ax.set_xscale('linear')
2317-
ax.figure.canvas.draw()
2318-
elif scalex == 'linear':
2319-
ax.set_xscale('log')
2320-
ax.figure.canvas.draw()
2321-
2322-
elif (event.key.isdigit() and event.key!='0') or event.key in all:
2323-
# keys in list 'all' enables all axes (default key 'a'),
2324-
# otherwise if key is a number only enable this particular axes
2325-
# if it was the axes, where the event was raised
2326-
if not (event.key in all):
2327-
n = int(event.key)-1
2328-
for i, a in enumerate(self.canvas.figure.get_axes()):
2329-
# consider axes, in which the event was raised
2330-
# FIXME: Why only this axes?
2331-
if event.x is not None and event.y is not None \
2332-
and a.in_axes(event):
2333-
if event.key in all:
2334-
a.set_navigate(True)
2335-
else:
2336-
a.set_navigate(i==n)
2337-
2351+
"""
2352+
implement the default mpl key bindings defined at
2353+
:ref:`key-event-handling`
2354+
"""
2355+
key_press_handler(event, self.canvas, self.canvas.toolbar)
23382356

23392357
def show_popup(self, msg):
23402358
"""

0 commit comments

Comments
 (0)