Как отследить мышь на холсте matplot в QWidget? - PullRequest
1 голос
/ 24 мая 2019

Я хочу отслеживать положение мыши на холсте matplot в режиме реального времени.

На данный момент я создал MplWidget, который наследует Qwidget (действует как контейнер), а затем построил поверх него холст, чтобы показать график. Однако проблема в том, что я могу отслеживать только положение мыши в области отступов, за исключением области холста.

Поскольку мой холст наследует matplotlib.figure, который не является QWidget, он не имеет атрибута 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!')

1 Ответ

1 голос
/ 24 мая 2019

Как вы заметили, холст обрабатывается не 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

В вашем случае вы должны использовать события:

  • button_press_event
  • button_release_event
  • motion_notify_event

Пример:

from PyQt5 import QtWidgets

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


class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(MplWidget, self).__init__(parent)
        self.canvas = FigureCanvas(Figure())

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

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

        self.canvas.mpl_connect("button_press_event", self.on_press)
        self.canvas.mpl_connect("button_release_event", self.on_release)
        self.canvas.mpl_connect("motion_notify_event", self.on_move)

    def on_press(self, event):
        print("press")
        print("event.xdata", event.xdata)
        print("event.ydata", event.ydata)
        print("event.inaxes", event.inaxes)
        print("x", event.x)
        print("y", event.y)

    def on_release(self, event):
        print("release:")
        print("event.xdata", event.xdata)
        print("event.ydata", event.ydata)
        print("event.inaxes", event.inaxes)
        print("x", event.x)
        print("y", event.y)

    def on_move(self, event):
        print("move")
        print("event.xdata", event.xdata)
        print("event.ydata", event.ydata)
        print("event.inaxes", event.inaxes)
        print("x", event.x)
        print("y", event.y)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MplWidget()
    w.show()
    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...