0

我正在开发一个基于 GUI 的过滤器设计和分析工具 ( https://github.com/chipmuenk/pyFDA ),子类化 matplotlib NavigationToolbar 以实现一些更改(添加/删除功能和按钮,新图标集)。完整代码可在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)

一般来说,这工作得很好,但是......

  1. ...“平移/缩放”和“缩放矩形”功能会引发以下错误(但仍然可以缩放和平移)。回溯(最近一次通话最后):

    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 不起作用,并且无论是否选择该功能也没有视觉提示。我必须承认,我不太了解组合功能 pan/zoom 的接口(QAction?)——我还不是一个经验丰富的 Pythonista。

  2. ...我的新功能“缩放全视图”有效,但无法使用“上一个/下一个视图”撤消缩放设置。这不足为奇,因为我没有将视图设置添加到视图设置列表(?)中,不知道从哪里开始:-)

谁能给我一个关于如何正确应用导航工具栏的小知识?

并且(无耻的插头:-)):有人愿意为该项目做出贡献吗?下一步将是 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
4

1 回答 1

0

使用原始 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”)。

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

self.myNavigationToolbar.push_current()

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

缺少鼠标修饰符的解决方案同样简单(当您知道如何操作时,即...),如 SO 帖子中所示

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

问题是,除非您“将 qt 的焦点激活到您的 mpl 画布上”,否则通常不会处理按键事件。解决方案是在 MplWidget 类中添加两行:

self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
self.canvas.setFocus()
于 2015-05-03T17:49:22.027 回答