【问题标题】:Matplotlib - Navigation Toolbar shortcuts not workingMatplotlib - 导航工具栏快捷方式不起作用
【发布时间】:2017-05-12 23:45:32
【问题描述】:

我在 PyQt4 UI 中嵌入了一个 matplotlib 图。类似的东西

Building a matplotlib GUI with Qt Designer.

QVBoxlayout中添加了FigureCanvasQTAgg和NavigationToolbar2QT,UI右侧是图形名称的QListWidget。

所有工具栏快捷方式都不起作用。我尝试改变 QVBoxlayout 和 QListWidget Widget 的焦点。

图生成为

from matplotlib.figure import Figure
fig=figure()
ax=fig.add_subplot(111)
ax.plot.plot(np.random.rand(5))

这个图被传递给 addmpl 方法,在该方法中生成画布和工具栏并添加到主窗口小部件。

def addmpl(self,fig):
    self.canvas = FigureCanvas(fig)
    self.mplvl.addWidget(self.canvas)
    self.canvas.draw()
    self.toolbar = NavigationToolbar(self.canvas,self.mplwindow)
    self.mplvl.addWidget(self.toolbar)

解决方法...

def menu(self):
    self.savefig=QtGui.QAction('&Save', self) 
    self.savefig.setShortcut('Ctrl+S')
    self.savefig.triggered.connect(self.save_figure)

    undo=QtGui.QAction('&Undo', self)
    undo.setShortcut('Ctrl+Z')
    undo.triggered.connect(self.back)

    redo=QtGui.QAction('&Redo', self)
    redo.setShortcut('Ctrl+Y')
    redo.triggered.connect(self.forward)

    figoptions=QtGui.QAction('&Figure Options', self)
    figoptions.setShortcut('Ctrl+F')
    figoptions.setStatusTip('Edit curves lines and axes parameters')
    figoptions.triggered.connect(self.edit_parameters)



def back(self):
    self.toolbar.back()
def forward(self):
    self.toolbar.forward()
def save_figure(self):
    self.toolbar.save_figure()
def edit_parameters(self):
    self.toolbar.edit_parameters()

但是诸如将平移/缩放限制到 x 轴之类的快捷方式 - 使用鼠标进行平移/缩放时按住 x 看起来很难实现且乏味。

这个Question的解决方法有同样的问题。(用NavigationToolbar2QT替换NavigationToolbar2QTAgg)

【问题讨论】:

  • 插槽是否被调用?即,如果您将打印语句放在 back() forward() 等中,您是否会在 GUI 启动的控制台中得到任何东西?如果不是,那么问题可能与工具栏的集成方式有关,而不是实际的 qaction,在这种情况下,您需要发布相关代码。
  • 我在 backend_bases.py 的 pan 方法中加入了 'print("Hello")'。按 p(平移的快捷方式)控制台保持为空。但是,如果我单击工具栏中的平移按钮,控制台会打印 Hello。
  • 示例代码可用here
  • 所以你的意思是工具栏按钮的键盘快捷键不起作用,但按钮操作确实有效(如果你点击它们)?
  • 是的...只有键盘快捷键不起作用...

标签: python qt matplotlib pyqt pyqt4


【解决方案1】:

没有看到初始化图形的代码部分,在查看了PyQt example 之后,我猜测你没有配置键盘快捷键:

  1. 确保您拥有from matplotlib.backend_bases import key_press_handler
  2. 将 matplotlib 图形画布的按键绑定到处理程序:

    self.fig = Figure(...)
    self.canvas = FigureCanvas(self.fig)
    self.mpl_nav_toolbar = NavigationToolbar(...)
    ...
    self.canvas.mpl_connect('key_press_event', self.on_key_press)
    
  3. 配置画布小部件以处理键盘事件:

    ...
    self.canvas.setFocusPolicy(Qt.StrongFocus)
    
  4. 定义您的处理程序以调用 key_press_handler:

    def on_key_press(self, event):
        key_press_handler(event, self.canvas, self.mpl_nav_toolbar)
    

顺便说一句,这些步骤也应该适用于 PyQt5。

【讨论】:

  • 也许这是关于焦点的错误......因为当我点击“T”按钮时,图形列表中的选择变为“Two Plot”......
  • 试过这个......但它没有工作......更新代码可用here....UI文件可用here.....
  • 添加 self.canvas.setFocusPolicy(Qt.StrongFocus) 和 self.canvas.setFocus() 解决了问题....感谢您指出正确的方向.....
  • 啊 thx 忘记了焦点策略,默认为无,所以我更新了答案。但是,我怀疑 setFocus() 是必需的:使用 StrongFocus,您应该能够通过 Tab 或单击画布或工具栏来让画布获得焦点。让我知道是否有更多我可以改进的答案。
【解决方案2】:

这是特定于 PyQt 的替代解决方案(使用 PyQt5 测试)。它不如 mpl_connect('key_press_event'...) 简洁,但允许更大的灵活性,例如重新定义快捷键。

NavigationToolbar2QT 继承自 QToolBar,而 QToolBar 又继承自 QWidget。因此,工具栏上的所有操作都可以通过 QWidget.actions() 获得。

例如,可以定义一个全局快捷方式并连接到缩放工具栏:

class Main(QMainWindow, Ui_MainWindow):
    def __init__(self, ):
        ...        
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Z), self)
        ....

    def addmpl(self, fig):
        ...
        for action in self.toolbar.actions():
            if action.text() == 'Zoom':
                self.shortcut.activated.connect(action.trigger)

【讨论】:

    猜你喜欢
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2016-11-06
    • 1970-01-01
    • 2015-10-12
    相关资源
    最近更新 更多