Matplotlib的'key_press_event'不响应

7

通过点击图形:

self.canvas.Fig.canvas.mpl_connect('button_press_event', self.button_press)

我可以接收信号并通过在状态栏中打印“按下按钮”来生成答案:

self.statusBar().showMessage("Key pressed", 400)

但由于某种原因,同样的代码片段对于按键(键盘)按下无效:

self.canvas.Fig.canvas.mpl_connect('key_press_event', self.key_press)

消息“按键已按下”不会出现,这意味着没有事件发生或者没有接收到信号。

这是包含所有基本类的MWE:

import sys
import matplotlib 
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas


class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100,data=[[]],timedelay=[],wavelength=[]):
        self.Fig = Figure(figsize=(width, height), dpi=dpi)
        self.Dataplot = self.Fig.add_subplot(111)

        self.compute_initial_figure(data,timedelay, wavelength)    

        FigureCanvas.__init__(self, self.Fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self,QSizePolicy.Expanding,QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self,data,timedelay,wavelength):
        pass

class MyStaticMplCanvas(MyMplCanvas):  
    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)

    def compute_initial_figure(self,data,timedelay,wavelength): 
        self.Dataplot.set_xlabel('Wavelength, nm')
        self.Dataplot.set_ylabel('Time delay, ~s')

class GraphView(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.main_widget = QtWidgets.QWidget(self)

        self.canvas = MyStaticMplCanvas(self.main_widget, width=8, height=8, dpi=100,data=[[]],timedelay=[],wavelength=[])

        self.canvas.Fig.canvas.mpl_connect('key_press_event', self.key_press)
        self.canvas.Fig.canvas.mpl_connect('button_press_event', self.button_press)

        self.layoutMain = QtWidgets.QHBoxLayout(self.main_widget)      
        self.layoutFigure = QtWidgets.QHBoxLayout()
        self.layoutMain.addLayout(self.layoutFigure)   
        self.layoutFigure.addWidget(self.canvas)


        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

    def key_press(self,event):
        self.statusBar().showMessage("Key pressed", 400)

    def button_press(self,event):
        self.statusBar().showMessage("Button pressed", 400) 

def main():
    app = QApplication( sys.argv )
    a=GraphView()
    a.show() 
    app.exec()

if __name__ == '__main__':
    sys.exit(main()) 

我的代码出了什么问题?

1
“不工作”是什么意思?代码是否产生错误?如果是,请发布完整的跟踪信息。 - hitzg
此外,提供的代码在我的机器上无法运行,在您的*app.exec()*行处产生了无效语法。 - Bas Jansen
1
@hitzg,我所说的不工作是指消息“按键已按下”未出现,这意味着没有事件发生或没有接收到信号。 - saldenisov
@saldenisov请在问题中提到这是针对Python 3的,因为提供的代码无法在Python 2.7上运行。 - Bas Jansen
@farenorth,有两个事件处理程序,一个用于鼠标按键,另一个用于键盘。用于键盘的那个对我不起作用。 - saldenisov
显示剩余2条评论
2个回答

9
我在这里找到了一个解决方案:链接 之后,
self.canvas = MyStaticMplCanvas(self.main_widget, width=8, height=8, dpi=100,data=[[]],timedelay=[],wavelength=[])

添加

self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
self.canvas.setFocus()

点击画布,使其获得焦点,从那时起,您将看到按键操作。


0

如果您不想每次使用键盘时都要点击画布,您可以执行以下操作,以便在光标悬停在画布上时自动将焦点更改为画布。将此添加到您的GraphView.__init__()中:

self.cid_enter = self.canvas.mpl_connect('axes_enter_event', self.on_enter_event)

并将on_enter_event方法添加到您的GraphView类中:

def on_enter_event(self, _):
    self.canvas.setFocus()

你也不需要改变FocusPolicy就可以使它工作。

顺便说一下,你不需要做self.canvas.Fig.canvas来引用canvas对象,因为它是循环的。 self.canvas已经是canvas对象了。理论上,你可以做self.canvas.Fig.canvas.Fig.canvas等等无限制地引用同一个对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接