-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
expose key press handler #717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import sys | ||
import numpy as np | ||
from matplotlib.figure import Figure | ||
from matplotlib.backend_bases import FigureManagerBase, key_press_handler | ||
from PyQt4.QtCore import * | ||
from PyQt4.QtGui import * | ||
|
||
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas | ||
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar | ||
|
||
|
||
class AppForm(QMainWindow): | ||
def __init__(self, parent=None): | ||
QMainWindow.__init__(self, parent) | ||
#self.x, self.y = self.get_data() | ||
self.data = self.get_data2() | ||
self.create_main_frame() | ||
self.on_draw() | ||
|
||
def create_main_frame(self): | ||
self.main_frame = QWidget() | ||
|
||
self.fig = Figure((5.0, 4.0), dpi=100) | ||
self.canvas = FigureCanvas(self.fig) | ||
self.canvas.setParent(self.main_frame) | ||
self.canvas.setFocusPolicy( Qt.StrongFocus ) | ||
self.canvas.setFocus() | ||
|
||
self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) | ||
|
||
self.canvas.mpl_connect('key_press_event', self.on_key_press) | ||
|
||
vbox = QVBoxLayout() | ||
vbox.addWidget(self.canvas) # the matplotlib canvas | ||
vbox.addWidget(self.mpl_toolbar) | ||
self.main_frame.setLayout(vbox) | ||
self.setCentralWidget(self.main_frame) | ||
|
||
def get_data2(self): | ||
return np.arange(20).reshape([4,5]).copy() | ||
|
||
def on_draw(self): | ||
self.fig.clear() | ||
self.axes = self.fig.add_subplot(111) | ||
#self.axes.plot(self.x, self.y, 'ro') | ||
self.axes.imshow(self.data, interpolation='nearest') | ||
#self.axes.plot([1,2,3]) | ||
self.canvas.draw() | ||
|
||
def on_key_press(self, event): | ||
print 'you pressed', event.key | ||
# implement the default mpl key press events described at | ||
# http://matplotlib.sourceforge.net/users/navigation_toolbar.html#navigation-keyboard-shortcuts | ||
key_press_handler(event, self.canvas, self.mpl_toolbar) | ||
|
||
def main(): | ||
app = QApplication(sys.argv) | ||
form = AppForm() | ||
form.show() | ||
app.exec_() | ||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1436,7 +1436,7 @@ def __init__(self, figure): | |
self.button_pick_id = self.mpl_connect('button_press_event',self.pick) | ||
self.scroll_pick_id = self.mpl_connect('scroll_event',self.pick) | ||
self.mouse_grabber = None # the axes currently grabbing mouse | ||
|
||
self.toolbar = None # NavigationToolbar2 will set me | ||
if False: | ||
## highlight the artists that are hit | ||
self.mpl_connect('motion_notify_event',self.onHilite) | ||
|
@@ -2213,6 +2213,110 @@ def stop_event_loop_default(self): | |
self._looping = False | ||
|
||
|
||
def key_press_handler(event, canvas, toolbar=None): | ||
""" | ||
Implement the default mpl key bindings for the canvas and toolbar | ||
described at :ref:`key-event-handling` | ||
|
||
*event* | ||
a :class:`KeyEvent` instance | ||
*canvas* | ||
a :class:`FigureCanvasBase` instance | ||
*toolbar* | ||
a :class:`NavigationToolbar2` instance | ||
|
||
""" | ||
# these bindings happen whether you are over an axes or not | ||
#if event.key == 'q': | ||
# self.destroy() # how cruel to have to destroy oneself! | ||
# return | ||
|
||
if event.key is None: | ||
return | ||
|
||
# Load key-mappings from your matplotlibrc file. | ||
fullscreen_keys = rcParams['keymap.fullscreen'] | ||
home_keys = rcParams['keymap.home'] | ||
back_keys = rcParams['keymap.back'] | ||
forward_keys = rcParams['keymap.forward'] | ||
pan_keys = rcParams['keymap.pan'] | ||
zoom_keys = rcParams['keymap.zoom'] | ||
save_keys = rcParams['keymap.save'] | ||
grid_keys = rcParams['keymap.grid'] | ||
toggle_yscale_keys = rcParams['keymap.yscale'] | ||
toggle_xscale_keys = rcParams['keymap.xscale'] | ||
all = rcParams['keymap.all_axes'] | ||
|
||
# toggle fullscreen mode (default key 'f') | ||
if event.key in fullscreen_keys: | ||
self.full_screen_toggle() | ||
|
||
if toolbar is not None: | ||
# home or reset mnemonic (default key 'h', 'home' and 'r') | ||
if event.key in home_keys: | ||
toolbar.home() | ||
# forward / backward keys to enable left handed quick navigation | ||
# (default key for backward: 'left', 'backspace' and 'c') | ||
elif event.key in back_keys: | ||
toolbar.back() | ||
# (default key for forward: 'right' and 'v') | ||
elif event.key in forward_keys: | ||
toolbar.forward() | ||
# pan mnemonic (default key 'p') | ||
elif event.key in pan_keys: | ||
toolbar.pan() | ||
# zoom mnemonic (default key 'o') | ||
elif event.key in zoom_keys: | ||
toolbar.zoom() | ||
# saving current figure (default key 's') | ||
elif event.key in save_keys: | ||
toolbar.save_figure() | ||
|
||
if event.inaxes is None: | ||
return | ||
|
||
# the mouse has to be over an axes to trigger these | ||
# switching on/off a grid in current axes (default key 'g') | ||
if event.key in grid_keys: | ||
event.inaxes.grid() | ||
canvas.draw() | ||
# toggle scaling of y-axes between 'log and 'linear' (default key 'l') | ||
elif event.key in toggle_yscale_keys: | ||
ax = event.inaxes | ||
scale = ax.get_yscale() | ||
if scale == 'log': | ||
ax.set_yscale('linear') | ||
ax.figure.canvas.draw() | ||
elif scale == 'linear': | ||
ax.set_yscale('log') | ||
ax.figure.canvas.draw() | ||
# toggle scaling of x-axes between 'log and 'linear' (default key 'k') | ||
elif event.key in toggle_xscale_keys: | ||
ax = event.inaxes | ||
scalex = ax.get_xscale() | ||
if scalex == 'log': | ||
ax.set_xscale('linear') | ||
ax.figure.canvas.draw() | ||
elif scalex == 'linear': | ||
ax.set_xscale('log') | ||
ax.figure.canvas.draw() | ||
|
||
elif (event.key.isdigit() and event.key!='0') or event.key in all: | ||
# keys in list 'all' enables all axes (default key 'a'), | ||
# otherwise if key is a number only enable this particular axes | ||
# if it was the axes, where the event was raised | ||
if not (event.key in all): | ||
n = int(event.key)-1 | ||
for i, a in enumerate(canvas.figure.get_axes()): | ||
# consider axes, in which the event was raised | ||
# FIXME: Why only this axes? | ||
if event.x is not None and event.y is not None \ | ||
and a.in_axes(event): | ||
if event.key in all: | ||
a.set_navigate(True) | ||
else: | ||
a.set_navigate(i==n) | ||
|
||
|
||
class FigureManagerBase: | ||
""" | ||
|
@@ -2224,7 +2328,7 @@ class FigureManagerBase: | |
A :class:`FigureCanvasBase` instance | ||
|
||
*num* | ||
The figure nuamber | ||
The figure number | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wasn't there a change that allowed for names for figures as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but this is converted from a string label to a number by the time it gets to the FigureManagerBase -- see pyplot.figure impl. So the docstring is correct here that this will be a number https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/pyplot.py#L318 |
||
""" | ||
def __init__(self, canvas, num): | ||
self.canvas = canvas | ||
|
@@ -2244,97 +2348,11 @@ def resize(self, w, h): | |
pass | ||
|
||
def key_press(self, event): | ||
|
||
# these bindings happen whether you are over an axes or not | ||
#if event.key == 'q': | ||
# self.destroy() # how cruel to have to destroy oneself! | ||
# return | ||
|
||
if event.key is None: | ||
return | ||
|
||
# Load key-mappings from your matplotlibrc file. | ||
fullscreen_keys = rcParams['keymap.fullscreen'] | ||
home_keys = rcParams['keymap.home'] | ||
back_keys = rcParams['keymap.back'] | ||
forward_keys = rcParams['keymap.forward'] | ||
pan_keys = rcParams['keymap.pan'] | ||
zoom_keys = rcParams['keymap.zoom'] | ||
save_keys = rcParams['keymap.save'] | ||
grid_keys = rcParams['keymap.grid'] | ||
toggle_yscale_keys = rcParams['keymap.yscale'] | ||
toggle_xscale_keys = rcParams['keymap.xscale'] | ||
all = rcParams['keymap.all_axes'] | ||
|
||
# toggle fullscreen mode (default key 'f') | ||
if event.key in fullscreen_keys: | ||
self.full_screen_toggle() | ||
|
||
# home or reset mnemonic (default key 'h', 'home' and 'r') | ||
elif event.key in home_keys: | ||
self.canvas.toolbar.home() | ||
# forward / backward keys to enable left handed quick navigation | ||
# (default key for backward: 'left', 'backspace' and 'c') | ||
elif event.key in back_keys: | ||
self.canvas.toolbar.back() | ||
# (default key for forward: 'right' and 'v') | ||
elif event.key in forward_keys: | ||
self.canvas.toolbar.forward() | ||
# pan mnemonic (default key 'p') | ||
elif event.key in pan_keys: | ||
self.canvas.toolbar.pan() | ||
# zoom mnemonic (default key 'o') | ||
elif event.key in zoom_keys: | ||
self.canvas.toolbar.zoom() | ||
# saving current figure (default key 's') | ||
elif event.key in save_keys: | ||
self.canvas.toolbar.save_figure() | ||
|
||
if event.inaxes is None: | ||
return | ||
|
||
# the mouse has to be over an axes to trigger these | ||
# switching on/off a grid in current axes (default key 'g') | ||
if event.key in grid_keys: | ||
event.inaxes.grid() | ||
self.canvas.draw() | ||
# toggle scaling of y-axes between 'log and 'linear' (default key 'l') | ||
elif event.key in toggle_yscale_keys: | ||
ax = event.inaxes | ||
scale = ax.get_yscale() | ||
if scale == 'log': | ||
ax.set_yscale('linear') | ||
ax.figure.canvas.draw() | ||
elif scale == 'linear': | ||
ax.set_yscale('log') | ||
ax.figure.canvas.draw() | ||
# toggle scaling of x-axes between 'log and 'linear' (default key 'k') | ||
elif event.key in toggle_xscale_keys: | ||
ax = event.inaxes | ||
scalex = ax.get_xscale() | ||
if scalex == 'log': | ||
ax.set_xscale('linear') | ||
ax.figure.canvas.draw() | ||
elif scalex == 'linear': | ||
ax.set_xscale('log') | ||
ax.figure.canvas.draw() | ||
|
||
elif (event.key.isdigit() and event.key!='0') or event.key in all: | ||
# keys in list 'all' enables all axes (default key 'a'), | ||
# otherwise if key is a number only enable this particular axes | ||
# if it was the axes, where the event was raised | ||
if not (event.key in all): | ||
n = int(event.key)-1 | ||
for i, a in enumerate(self.canvas.figure.get_axes()): | ||
# consider axes, in which the event was raised | ||
# FIXME: Why only this axes? | ||
if event.x is not None and event.y is not None \ | ||
and a.in_axes(event): | ||
if event.key in all: | ||
a.set_navigate(True) | ||
else: | ||
a.set_navigate(i==n) | ||
|
||
""" | ||
implement the default mpl key bindings defined at | ||
:ref:`key-event-handling` | ||
""" | ||
key_press_handler(event, self.canvas, self.canvas.toolbar) | ||
|
||
def show_popup(self, msg): | ||
""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I think I would rather see these tags done like so:
.. _gallery_tags::
:key-event-handling:
:foo-tag:
:spam-tag:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nm, I had a brain fart and didn't realize it was a reference tag.