PyQt5 通过 QLabel 对象进行鼠标跟踪

sla*_*hip 4 python events event-tracking qlabel pyqt5

我正在使用 PyQt5 创建一个应用程序。该应用程序有一个带有多个小部件的主窗口。其中一个小部件是显示视频的 QLabel 对象。当我检查单选按钮时,我想跟踪光标并在将鼠标悬停在视频上时显示光标坐标。

\n\n

我创建了一个 MouseTracking 类,我将 QLabel 对象传递给该类window。我已经通过打印其几何图形来验证是否已将其传递到类中。但我\xe2\x80\x99m 不知何故没有将鼠标跟踪与window. 这是 MouseTracking 类的代码。我究竟做错了什么?

\n\n
class MouseTracker(QLabel):\n    def __init__(self, window):\n        super().__init__(window)\n        self.window = window\n        self.window.setMouseTracking(True)\n        self.initUI()\n\n    def initUI(self):\n        self.label = QLabel(self)\n        self.label.setAlignment(Qt.AlignCenter)\n        self.label.setStyleSheet(\'background-color: white; border: 1px solid black\')\n        self.show()\n\n    def mouseMoveEvent(self, event):\n        x = event.x()\n        y = event.y()\n        print("X, Y = ", x, y)\n        self.label.setGeometry(x+30, y-15, 90, 40)\n        self.label.setText(\'(%d, %d)\' % (x, y))\n
Run Code Online (Sandbox Code Playgroud)\n

eyl*_*esc 5

在您的代码中,您已启用“窗口”的 mouseTracking 属性,但您正在监视 MouseTracker 的 mouseMoveEvent 方法,这是不正确的。如果您想跟踪小部件的事件而不覆盖任何方法,那么您必须使用事件过滤器。

在下面的示例中,我尝试根据您的描述实现您的应用程序,例如绿色 QLabel 代表视频显示的 QLabel。综合以上情况,解决方案如下:

from PyQt5 import QtCore, QtGui, QtWidgets


class MouseTracker(QtCore.QObject):
    positionChanged = QtCore.pyqtSignal(QtCore.QPoint)

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self.widget.setMouseTracking(True)
        self.widget.installEventFilter(self)

    @property
    def widget(self):
        return self._widget

    def eventFilter(self, o, e):
        if o is self.widget and e.type() == QtCore.QEvent.MouseMove:
            self.positionChanged.emit(e.pos())
        return super().eventFilter(o, e)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)

        self.video_label = QtWidgets.QLabel()
        self.video_label.setStyleSheet("background-color: green; border: 1px solid black")

        tracker = MouseTracker(self.video_label)
        tracker.positionChanged.connect(self.on_positionChanged)

        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(self.video_label)
        lay.addWidget(QtWidgets.QLabel())

        self.resize(640, 480)

        self.label_position = QtWidgets.QLabel(
            self.video_label, alignment=QtCore.Qt.AlignCenter
        )
        self.label_position.setStyleSheet('background-color: white; border: 1px solid black')

    @QtCore.pyqtSlot(QtCore.QPoint)
    def on_positionChanged(self, pos):
        delta = QtCore.QPoint(30, -15)
        self.label_position.show()
        self.label_position.move(pos + delta)
        self.label_position.setText("(%d, %d)" % (pos.x(), pos.y()))
        self.label_position.adjustSize()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述