Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df0a112

Browse files
pelsonpelson
pelson
authored andcommitted
Several fixes to WX. Modifier keys implemented for qt, wx and gtk backends.
1 parent 3bbbd0a commit df0a112

File tree

4 files changed

+66
-62
lines changed

4 files changed

+66
-62
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,8 +2767,6 @@ def drag_zoom(self, event):
27672767

27682768
self.draw_rubberband(event, x, y, lastx, lasty)
27692769

2770-
2771-
27722770
def release_zoom(self, event):
27732771
'the release mouse button callback in zoom to rect mode'
27742772
for zoom_id in self._ids_zoom:
@@ -2894,8 +2892,6 @@ def draw(self):
28942892
loc.refresh()
28952893
self.canvas.draw()
28962894

2897-
2898-
28992895
def _update_view(self):
29002896
'''update the viewlim and position from the view and
29012897
position stack for each axes

lib/matplotlib/backends/backend_gtk.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,17 @@ def enter_notify_event(self, widget, event):
322322
def _get_key(self, event):
323323
if event.keyval in self.keyvald:
324324
key = self.keyvald[event.keyval]
325-
elif event.keyval <256:
325+
elif event.keyval < 256:
326326
key = chr(event.keyval)
327327
else:
328328
key = None
329329

330-
ctrl = event.state & gdk.CONTROL_MASK
331-
shift = event.state & gdk.SHIFT_MASK
332-
return key
330+
for key_mask, prefix in ([gdk.CONTROL_MASK, 'ctrl'],
331+
[gdk.MOD1_MASK, 'alt'], ):
332+
if event.state & key_mask:
333+
key = '{}+{}'.format(prefix, key)
334+
335+
return key
333336

334337

335338
def configure_event(self, widget, event):

lib/matplotlib/backends/backend_qt4.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import division, print_function
22
import math
33
import os
4+
import signal
45
import sys
56

67
import matplotlib
@@ -60,8 +61,10 @@ def _create_qApp():
6061

6162
class Show(ShowBase):
6263
def mainloop(self):
63-
QtGui.qApp.exec_()
64+
# allow KeyboardInterrupt exceptions to close the plot window.
65+
signal.signal(signal.SIGINT, signal.SIG_DFL)
6466

67+
QtGui.qApp.exec_()
6568
show = Show()
6669

6770

@@ -268,13 +271,36 @@ def minumumSizeHint( self ):
268271
def _get_key( self, event ):
269272
if event.isAutoRepeat():
270273
return None
274+
271275
if event.key() < 256:
272-
key = str(event.text())
276+
key = unicode(event.text())
277+
278+
# if the control key is being pressed, we don't get the correct
279+
# characters, so interpret them directly from the event.key().
280+
# Unfortunately, this means that we cannot handle key's case
281+
# since event.key() is not case sensitve, whereas event.text() is,
282+
# Finally, since it is not possible to get the CapsLock state
283+
# we cannot accurately compute the case of a pressed key when
284+
# ctrl+shift+p is pressed.
285+
if int(event.modifiers()) & QtCore.Qt.ControlModifier and event.key() < 256:
286+
# we always get an uppercase charater
287+
key = chr(event.key())
288+
# if shift is not being pressed, lowercase it (as mentioned,
289+
# this does not take into account the CapsLock state)
290+
if not int(event.modifiers()) & QtCore.Qt.ShiftModifier:
291+
key = key.lower()
292+
273293
elif event.key() in self.keyvald:
274-
key = self.keyvald[ event.key() ]
294+
key = self.keyvald[event.key()]
275295
else:
276296
key = None
277297

298+
if key is not None:
299+
for modifier, Qt_key, prefix in [(QtCore.Qt.ControlModifier, QtCore.Qt.Key_Control, 'ctrl'),
300+
(QtCore.Qt.AltModifier, QtCore.Qt.Key_Alt, 'alt')]:
301+
if event.key() != Qt_key and int(event.modifiers()) & modifier == modifier:
302+
key = '{}+{}'.format(prefix, key)
303+
278304
return key
279305

280306
def new_timer(self, *args, **kwargs):

lib/matplotlib/backends/backend_wx.py

Lines changed: 30 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,13 +1242,18 @@ def _get_key(self, evt):
12421242
keyval = evt.m_keyCode
12431243
if keyval in self.keyvald:
12441244
key = self.keyvald[keyval]
1245-
elif keyval <256:
1245+
elif keyval < 256:
12461246
key = chr(keyval)
1247+
# wx always returns an uppercase, so make it lowercase if the shift
1248+
# key is not depressed (NOTE: this will not handle Caps Lock)
1249+
if not evt.ShiftDown():
1250+
key = key.lower()
12471251
else:
12481252
key = None
12491253

1250-
# why is wx upcasing this?
1251-
if key is not None: key = key.lower()
1254+
for meth, prefix in ([evt.ControlDown, 'ctrl'], [evt.AltDown, 'alt'], ):
1255+
if meth():
1256+
key = '{}+{}'.format(prefix, key)
12521257

12531258
return key
12541259

@@ -1476,6 +1481,7 @@ def __init__(self, num, fig):
14761481
self.SetStatusBar(statbar)
14771482
self.canvas = self.get_canvas(fig)
14781483
self.canvas.SetInitialSize(wx.Size(fig.bbox.width, fig.bbox.height))
1484+
self.canvas.SetFocus()
14791485
self.sizer =wx.BoxSizer(wx.VERTICAL)
14801486
self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)
14811487
# By adding toolbar in sizer, we are able to put it at the bottom
@@ -1742,8 +1748,6 @@ def updateButtonText(self, lst):
17421748
self.SetLabel("Axes: %s" % axis_txt[:-1])
17431749

17441750

1745-
1746-
17471751
cursord = {
17481752
cursors.MOVE : wx.CURSOR_HAND,
17491753
cursors.HAND : wx.CURSOR_HAND,
@@ -1787,57 +1791,33 @@ def _init_toolbar(self):
17871791
DEBUG_MSG("_init_toolbar", 1, self)
17881792

17891793
self._parent = self.canvas.GetParent()
1790-
_NTB2_HOME =wx.NewId()
1791-
self._NTB2_BACK =wx.NewId()
1792-
self._NTB2_FORWARD =wx.NewId()
1793-
self._NTB2_PAN =wx.NewId()
1794-
self._NTB2_ZOOM =wx.NewId()
1795-
_NTB2_SAVE = wx.NewId()
1796-
_NTB2_SUBPLOT =wx.NewId()
1797-
1798-
self.SetToolBitmapSize(wx.Size(24,24))
1799-
1800-
self.AddSimpleTool(_NTB2_HOME, _load_bitmap('home.png'),
1801-
'Home', 'Reset original view')
1802-
self.AddSimpleTool(self._NTB2_BACK, _load_bitmap('back.png'),
1803-
'Back', 'Back navigation view')
1804-
self.AddSimpleTool(self._NTB2_FORWARD, _load_bitmap('forward.png'),
1805-
'Forward', 'Forward navigation view')
1806-
# todo: get new bitmap
1807-
self.AddCheckTool(self._NTB2_PAN, _load_bitmap('move.png'),
1808-
shortHelp='Pan',
1809-
longHelp='Pan with left, zoom with right')
1810-
self.AddCheckTool(self._NTB2_ZOOM, _load_bitmap('zoom_to_rect.png'),
1811-
shortHelp='Zoom', longHelp='Zoom to rectangle')
18121794

1813-
self.AddSeparator()
1814-
self.AddSimpleTool(_NTB2_SUBPLOT, _load_bitmap('subplots.png'),
1815-
'Configure subplots', 'Configure subplot parameters')
18161795

1817-
self.AddSimpleTool(_NTB2_SAVE, _load_bitmap('filesave.png'),
1818-
'Save', 'Save plot contents to file')
1819-
1820-
bind(self, wx.EVT_TOOL, self.home, id=_NTB2_HOME)
1821-
bind(self, wx.EVT_TOOL, self.forward, id=self._NTB2_FORWARD)
1822-
bind(self, wx.EVT_TOOL, self.back, id=self._NTB2_BACK)
1823-
bind(self, wx.EVT_TOOL, self.zoom, id=self._NTB2_ZOOM)
1824-
bind(self, wx.EVT_TOOL, self.pan, id=self._NTB2_PAN)
1825-
bind(self, wx.EVT_TOOL, self.configure_subplot, id=_NTB2_SUBPLOT)
1826-
bind(self, wx.EVT_TOOL, self.save, id=_NTB2_SAVE)
1796+
self.wx_ids = {}
1797+
for text, tooltip_text, image_file, callback in self.toolitems:
1798+
if text is None:
1799+
self.AddSeparator()
1800+
continue
1801+
self.wx_ids[text] = wx.NewId()
1802+
if text in ['Pan', 'Zoom']:
1803+
self.AddCheckTool(self.wx_ids[text], _load_bitmap(image_file + '.png'),
1804+
shortHelp=text, longHelp=tooltip_text)
1805+
else:
1806+
self.AddSimpleTool(self.wx_ids[text], _load_bitmap(image_file + '.png'),
1807+
text, tooltip_text)
1808+
bind(self, wx.EVT_TOOL, getattr(self, callback), id=self.wx_ids[text])
18271809

18281810
self.Realize()
18291811

1830-
18311812
def zoom(self, *args):
1832-
self.ToggleTool(self._NTB2_PAN, False)
1813+
self.ToggleTool(self.wx_ids['Pan'], False)
18331814
NavigationToolbar2.zoom(self, *args)
18341815

18351816
def pan(self, *args):
1836-
self.ToggleTool(self._NTB2_ZOOM, False)
1817+
self.ToggleTool(self.wx_ids['Zoom'], False)
18371818
NavigationToolbar2.pan(self, *args)
18381819

1839-
1840-
def configure_subplot(self, evt):
1820+
def configure_subplots(self, evt):
18411821
frame = wx.Frame(None, -1, "Configure subplots")
18421822

18431823
toolfig = Figure((6,3))
@@ -1855,7 +1835,7 @@ def configure_subplot(self, evt):
18551835
tool = SubplotTool(self.canvas.figure, toolfig)
18561836
frame.Show()
18571837

1858-
def save(self, evt):
1838+
def save_figure(self, *args):
18591839
# Fetch the required filename and file type.
18601840
filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
18611841
default_file = "image." + self.canvas.get_default_filetype()
@@ -1881,7 +1861,7 @@ def save(self, evt):
18811861
os.path.join(dirname, filename), format=format)
18821862
except Exception as e:
18831863
error_msg_wx(str(e))
1884-
1864+
18851865
def set_cursor(self, cursor):
18861866
cursor =wx.StockCursor(cursord[cursor])
18871867
self.canvas.SetCursor( cursor )
@@ -1948,8 +1928,8 @@ def set_message(self, s):
19481928
def set_history_buttons(self):
19491929
can_backward = (self._views._pos > 0)
19501930
can_forward = (self._views._pos < len(self._views._elements) - 1)
1951-
self.EnableTool(self._NTB2_BACK, can_backward)
1952-
self.EnableTool(self._NTB2_FORWARD, can_forward)
1931+
self.EnableTool(self.wx_ids['Back'], can_backward)
1932+
self.EnableTool(self.wx_ids['Forward'], can_forward)
19531933

19541934

19551935
class NavigationToolbarWx(wx.ToolBar):
@@ -2149,13 +2129,12 @@ def _onMouseWheel(self, evt):
21492129
direction = -1
21502130
self.button_fn(direction)
21512131

2152-
_onSave = NavigationToolbar2Wx.save
2132+
_onSave = NavigationToolbar2Wx.save_figure
21532133

21542134
def _onClose(self, evt):
21552135
self.GetParent().Destroy()
21562136

21572137

2158-
21592138
class StatusBarWx(wx.StatusBar):
21602139
"""
21612140
A status bar is added to _FigureFrame to allow measurements and the

0 commit comments

Comments
 (0)