子类化 matplotlib NavigationToolbar 会引发平移/缩放错误
Subclassing matplotlib NavigationToolbar throws error with Pan / Zoom
我正在开发一个基于 GUI 的过滤器设计和分析工具(https://github.com/chipmuenk/pyFDA), subclassing matplotlib NavigationToolbar to implement some changes (added / deleted functions and buttons, new icon set). The full code is available under https://github.com/chipmuenk/pyFDA/。每个(选项卡式的)plot_* 小部件实例化子类 NavigationToolbar 的副本,例如来自 plot_widgets/plot_phi.py :
from plot_widgets.plot_utils import MplWidget
class PlotPhi(QtGui.QMainWindow):
def __init__(self, parent = None, DEBUG = False): # default parent = None -> top Window
super(PlotPhi, self).__init__(parent)
self.mplwidget = MplWidget()
self.mplwidget.setFocus()
self.setCentralWidget(self.mplwidget)
ax = self.mplwidget.fig.add_subplot(111)
总的来说,这很好用,但是...
... 函数 "pan / zoom" 和 "zoom rectangle" 会抛出以下错误(但仍然会缩放和平移)。
追溯(最近一次通话最后一次):
File "D:\Programme\WinPython-64bit-3.4.3.1\python-3.4.3.amd64\lib\site-
packages\matplotlib\backends\backend_qt5.py",
line 666, in zoom
self._update_buttons_checked()
File "D:\Programme\WinPython-64bit-3.4.3.1\python-3.4.3.amd64\lib\site-
packages\matplotlib\backends\backend_qt5.py",
line 657, in _update_buttons_checked
self._actions['pan'].setChecked(self._active == 'PAN')
KeyError: 'pan'
鼠标修饰符 x 和 y 不起作用,也没有视觉提示是否选择了该功能。我必须承认,我不太了解组合函数的接口(QAction?)pan/zoom - 我还不是一个经验丰富的 Pythonista。
...我的新功能 "zoom full view" 有效,但使用 "previous / next view" 无法撤消缩放设置。这并不奇怪,因为我没有将视图设置添加到视图设置列表(?)中,不知道从哪里开始:-)
谁能教我如何正确应用导航工具栏?
并且(无耻的插件:-)):有人愿意为这个项目做贡献吗?接下来的步骤将是 VHDL/Verilog - 使用 myHDL (http://myhdl.org) 导出并保存/加载过滤器功能
这是来自 plot_widgets/plot_utils.py
的剪辑片段
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.backend_bases import cursors as mplCursors
from matplotlib.figure import Figure
class MyMplToolbar(NavigationToolbar):
"""
Custom Matplotlib Navigationtoolbar, subclassed from
NavigationToolbar.
derived from http://www.python-forum.de/viewtopic.php?f=24&t=26437
"""
def _init_toolbar(self):
# self.basedir = os.path.join(rcParams[ 'datapath' ], 'images/icons')
iconDir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'..','images','icons', '')
# HOME:
a = self.addAction(QtGui.QIcon(iconDir + 'home.svg'), \
'Home', self.home)
a.setToolTip('Reset original view')
# BACK:
a = self.addAction(QtGui.QIcon(iconDir + 'action-undo.svg'), \
'Back', self.back)
a.setToolTip('Back to previous view')
# PAN:
a = self.addAction(QtGui.QIcon(iconDir + 'move.svg'), \
'Pan', self.pan)
# 'Pan', self.pan('self.move','self.pan')) # nearly works ...
a.setToolTip('Pan axes with left mouse button, zoom with right')
# ZOOM RECTANGLE:
a = self.addAction(QtGui.QIcon(iconDir + 'magnifying-glass.svg'), \
'Zoom', self.zoom)
a.setToolTip('Zoom in / out to rectangle with left / right mouse button.')
# Full View:
a = self.addAction(QtGui.QIcon(iconDir + 'fullscreen-enter.svg'), \
'Full View', self.parent.pltFullView)
a.setToolTip('Full view')
self.buttons = {}
# reference holder for subplots_adjust window
self.adj_window = None
对原始 NavigationToolbar 进行一些逆向工程显示了一些缺失的位:
# PAN:
self.a_pa = self.addAction(QtGui.QIcon(iconDir + 'move.svg'), \
'Pan', self.pan)
self.a_pa.setToolTip('Pan axes with left mouse button, zoom with right')
self._actions['pan'] = self.a_pa
self.a_pa.setCheckable(True)
self.a_pa.setEnabled(True) # enable / disable function programwise
以上代码消除了错误并给出了是否选择了 Pan 的视觉提示 ("setCheckable")。
可以通过调用
轻松地将"full view"添加到查看限制的历史记录中
self.myNavigationToolbar.push_current()
在 更改视图之前(例如通过自动缩放)。
如 SO post
中所示,解决缺少鼠标修饰符的方法同样简单(如果您知道如何操作,那就是...)
matplotlib and Qt: mouse press event.key is always None
The issue is that key press events in general are not processed unless you "activate the focus of qt onto your mpl canvas". The solution is to add two lines to the MplWidget class:
self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
self.canvas.setFocus()
我正在开发一个基于 GUI 的过滤器设计和分析工具(https://github.com/chipmuenk/pyFDA), subclassing matplotlib NavigationToolbar to implement some changes (added / deleted functions and buttons, new icon set). The full code is available under https://github.com/chipmuenk/pyFDA/。每个(选项卡式的)plot_* 小部件实例化子类 NavigationToolbar 的副本,例如来自 plot_widgets/plot_phi.py :
from plot_widgets.plot_utils import MplWidget
class PlotPhi(QtGui.QMainWindow):
def __init__(self, parent = None, DEBUG = False): # default parent = None -> top Window
super(PlotPhi, self).__init__(parent)
self.mplwidget = MplWidget()
self.mplwidget.setFocus()
self.setCentralWidget(self.mplwidget)
ax = self.mplwidget.fig.add_subplot(111)
总的来说,这很好用,但是...
... 函数 "pan / zoom" 和 "zoom rectangle" 会抛出以下错误(但仍然会缩放和平移)。 追溯(最近一次通话最后一次):
File "D:\Programme\WinPython-64bit-3.4.3.1\python-3.4.3.amd64\lib\site- packages\matplotlib\backends\backend_qt5.py", line 666, in zoom self._update_buttons_checked() File "D:\Programme\WinPython-64bit-3.4.3.1\python-3.4.3.amd64\lib\site- packages\matplotlib\backends\backend_qt5.py", line 657, in _update_buttons_checked self._actions['pan'].setChecked(self._active == 'PAN') KeyError: 'pan'
鼠标修饰符 x 和 y 不起作用,也没有视觉提示是否选择了该功能。我必须承认,我不太了解组合函数的接口(QAction?)pan/zoom - 我还不是一个经验丰富的 Pythonista。
...我的新功能 "zoom full view" 有效,但使用 "previous / next view" 无法撤消缩放设置。这并不奇怪,因为我没有将视图设置添加到视图设置列表(?)中,不知道从哪里开始:-)
谁能教我如何正确应用导航工具栏?
并且(无耻的插件:-)):有人愿意为这个项目做贡献吗?接下来的步骤将是 VHDL/Verilog - 使用 myHDL (http://myhdl.org) 导出并保存/加载过滤器功能
这是来自 plot_widgets/plot_utils.py
的剪辑片段from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.backend_bases import cursors as mplCursors
from matplotlib.figure import Figure
class MyMplToolbar(NavigationToolbar):
"""
Custom Matplotlib Navigationtoolbar, subclassed from
NavigationToolbar.
derived from http://www.python-forum.de/viewtopic.php?f=24&t=26437
"""
def _init_toolbar(self):
# self.basedir = os.path.join(rcParams[ 'datapath' ], 'images/icons')
iconDir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'..','images','icons', '')
# HOME:
a = self.addAction(QtGui.QIcon(iconDir + 'home.svg'), \
'Home', self.home)
a.setToolTip('Reset original view')
# BACK:
a = self.addAction(QtGui.QIcon(iconDir + 'action-undo.svg'), \
'Back', self.back)
a.setToolTip('Back to previous view')
# PAN:
a = self.addAction(QtGui.QIcon(iconDir + 'move.svg'), \
'Pan', self.pan)
# 'Pan', self.pan('self.move','self.pan')) # nearly works ...
a.setToolTip('Pan axes with left mouse button, zoom with right')
# ZOOM RECTANGLE:
a = self.addAction(QtGui.QIcon(iconDir + 'magnifying-glass.svg'), \
'Zoom', self.zoom)
a.setToolTip('Zoom in / out to rectangle with left / right mouse button.')
# Full View:
a = self.addAction(QtGui.QIcon(iconDir + 'fullscreen-enter.svg'), \
'Full View', self.parent.pltFullView)
a.setToolTip('Full view')
self.buttons = {}
# reference holder for subplots_adjust window
self.adj_window = None
对原始 NavigationToolbar 进行一些逆向工程显示了一些缺失的位:
# PAN:
self.a_pa = self.addAction(QtGui.QIcon(iconDir + 'move.svg'), \
'Pan', self.pan)
self.a_pa.setToolTip('Pan axes with left mouse button, zoom with right')
self._actions['pan'] = self.a_pa
self.a_pa.setCheckable(True)
self.a_pa.setEnabled(True) # enable / disable function programwise
以上代码消除了错误并给出了是否选择了 Pan 的视觉提示 ("setCheckable")。
可以通过调用
轻松地将"full view"添加到查看限制的历史记录中self.myNavigationToolbar.push_current()
在 更改视图之前(例如通过自动缩放)。
如 SO post
中所示,解决缺少鼠标修饰符的方法同样简单(如果您知道如何操作,那就是...)matplotlib and Qt: mouse press event.key is always None
The issue is that key press events in general are not processed unless you "activate the focus of qt onto your mpl canvas". The solution is to add two lines to the MplWidget class:
self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
self.canvas.setFocus()