子类化 matplotlib NavigationToolbar 在平移/缩放时引发错误 [英] Subclassing matplotlib NavigationToolbar throws error with Pan / Zoom

查看:64
本文介绍了子类化 matplotlib NavigationToolbar 在平移/缩放时引发错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发基于GUI的过滤器设计和分析工具( https://github.com/chipmuenk/pyFDA),子类化 matplotlib NavigationToolbar 以实现一些更改(添加/删除功能和按钮,新图标集).完整代码可在 https://github.com/chipmuenk/pyFDA/下找到.每个(选项卡式) plot_* 小部件实例化子类导航工具栏的副本,例如来自plot_widgets/plot_phi.py:

I'm developing a GUI based filter design and analysis tool (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/ . Each (tabbed) plot_* widget instantiates a copy of the subclassed NavigationToolbar, e.g. from 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)

通常,这很好,但是...

In general, this works quite well but ...

  1. ...函数平移/缩放"和缩放矩形"会引发以下错误(但是仍然缩放和平移).追溯(最近一次通话):

  1. ... the functions "pan / zoom" and "zoom rectangle" throw the following error (but zoom and pan nevertheless). Traceback (most recent call last):

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?)-我还不是经验丰富的Pythonista.

The mouse modifiers x and y are not working and there is also no visual cue whether the function is selected or not. I must admit, I don't quite understand the interface (QAction?) to the combinated functions pan/zoom - I'm not a well seasoned Pythonista yet.

...我的新功能缩放全屏"有效,但无法使用上一个/下一个视图"撤消缩放设置.这并不奇怪,因为我不将视图设置添加到视图设置列表(?)中,也不知道从何处开始:-)

...my new function "zoom full view" works but the zoom setting cannot be undone using "previous / next view". This comes as no big surprise as I don't add the view setting to the list (?) of view settings, not knowing where to start :-)

谁能告诉我如何正确应用导航工具栏?

Who could be so kind to give me a little jump start on how to properly apply the Navigation Toolbar?

而且(无耻的插件:-)):有人愿意为该项目做出贡献吗?下一步将是VHDL/Verilog-使用myHDL( http://myhdl.org )导出并保存/加载过滤器功能

And (shameless plug :-) ): Anyone caring to contribute to the project? Next steps will be VHDL / Verilog - Export using myHDL (http://myhdl.org) and save / load filter functionality

这是来自 plot_widgets/plot_utils.py 的修剪片段

This is a trimmed snippet from 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 进行一些逆向工程时发现了一些缺失的部分:

Doing some reverse engineering with the original NavigationToolbar showed me some missing bits:

# 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").

The above code eliminates the error and gives the visual cue ("setCheckable") to whether Pan is selected or not.

通过调用可以轻松地将完整视图"添加到视图限制的历史记录中

The "full view" can easily be added to the history of view limits by calling

self.myNavigationToolbar.push_current()

之前更改视图(例如通过自动缩放).

before changing the view (e.g. by autoscale).

丢失鼠标修饰符的解决方案同样简单(当您知道如何做时,那就是......),如 SO 帖子中所示

The solution to the missing mouse modifiers is equally simple (when you know how, that is ...) as shown in the SO post

matplotlib 和 Qt:鼠标按下 event.key总是无

问题在于,除非您将qt的焦点激活到mpl画布上",否则一般不会处理按键事件.解决方法是在 MplWidget 类中添加两行:

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()

这篇关于子类化 matplotlib NavigationToolbar 在平移/缩放时引发错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆