如何在QWidget中的matplot画布上跟踪鼠标?

YUN*_*ANG 4 python pyqt matplotlib pyqt5

我想实时跟踪鼠标在 matplot 画布上的位置。

现在,我构建了一个继承 Qwidget 的 MplWidget(就像一个容器),然后在它上面构建了一个画布来显示绘图。但是,问题是我只能在除画布区域之外的填充区域中跟踪鼠标的位置。

由于我的画布继承了不是 QWidget 的 matplotlib.figure,因此它没有 setMouseTracking() 属性。这样,如何解决这个问题呢?

我找到了一个非常有用的链接如何实时返回鼠标坐标?. 然而,它也面临同样的问题。当鼠标悬停在标签(文本区域)上时,跟踪功能似乎被中断了。

我的这个类的代码显示在这里:

from PyQt5.QtWidgets import *

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

from matplotlib.figure import Figure


class MplWidget(QWidget):

    def __init__(self, parent=None):
        # QWidget.__init__(self, parent)
        super(QWidget, self).__init__(parent)

        self.canvas = FigureCanvas(Figure())

        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.canvas)

        self.canvas.axes = self.canvas.figure.add_subplot(111)
        self.setLayout(vertical_layout)

        self.setMouseTracking(True)

    def mouseMoveEvent(self, e):
        text = "x: {0},  y: {1}".format(e.x(), e.y())
        print(text)
        super(MplWidget, self).mouseMoveEvent(e)

    def mousePressEvent(self, e):
        print('click!')
Run Code Online (Sandbox Code Playgroud)

eyl*_*esc 6

正如您所注意到的,画布不是由 Qt 处理的,而是由 matplotlib 处理的,因此解决方案是使用该库提供的事件,如果您查看文档,您会发现有以下事件:

事件名称 类和描述

'button_press_event'  MouseEvent - mouse button is pressed
'button_release_event'    MouseEvent - mouse button is released
'draw_event'  DrawEvent - canvas draw (but before screen update)
'key_press_event' KeyEvent - key is pressed
'key_release_event'   KeyEvent - key is released
'motion_notify_event' MouseEvent - mouse motion
'pick_event'  PickEvent - an object in the canvas is selected
'resize_event'    ResizeEvent - figure canvas is resized
'scroll_event'    MouseEvent - mouse scroll wheel is rolled
'figure_enter_event'  LocationEvent - mouse enters a new figure
'figure_leave_event'  LocationEvent - mouse leaves a figure
'axes_enter_event'    LocationEvent - mouse enters a new axes
'axes_leave_event'    LocationEvent - mouse leaves an axes
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您应该使用事件:

  • button_press_event
  • button_release_event
  • 运动通知事件

例子:

'button_press_event'  MouseEvent - mouse button is pressed
'button_release_event'    MouseEvent - mouse button is released
'draw_event'  DrawEvent - canvas draw (but before screen update)
'key_press_event' KeyEvent - key is pressed
'key_release_event'   KeyEvent - key is released
'motion_notify_event' MouseEvent - mouse motion
'pick_event'  PickEvent - an object in the canvas is selected
'resize_event'    ResizeEvent - figure canvas is resized
'scroll_event'    MouseEvent - mouse scroll wheel is rolled
'figure_enter_event'  LocationEvent - mouse enters a new figure
'figure_leave_event'  LocationEvent - mouse leaves a figure
'axes_enter_event'    LocationEvent - mouse enters a new axes
'axes_leave_event'    LocationEvent - mouse leaves an axes
Run Code Online (Sandbox Code Playgroud)