PyQt5 中的鼠标悬停事件

Mouseover Event in PyQt5

我想获取鼠标悬停在标签上时的位置。我读 this 但我的问题不同。我需要抓住鼠标位置,因为它悬停在我的标签上而不点击所以,mouseMoveEvent 没有帮助

这是我的代码:

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.WindowGUI()
        self.level = "Image Not Loaded Yet"
        self.mouseIsClicked = False
        self.top = 90
        self.left = 90
        self.height = 1800
        self.width = 1800
        self.setGeometry(self.top, self.left, self.height, self.width)
        self.setWindowTitle("Manual Contact Andgle")
        self.setMouseTracking(True)
        mainWidget = QWidget(self)
        self.setCentralWidget(mainWidget)
        mainWidget.setLayout(self.finalVbox)

        self.show()

    def WindowGUI(self):
        self.finalVbox = QVBoxLayout()  # Final Layout
        self.mainHBox = QHBoxLayout()  # Hbox for picLable and Buttons
        self.mainVBox = QVBoxLayout()  # VBox for two Groupboxes
        self.lineVBox = QVBoxLayout()  # VBox For Line Drawing Buttons
        self.fileVBox = QVBoxLayout()  # VBox for file Loading and Saving Buttons
        self.lineGroupbox = QGroupBox("Drawing")  # GroupBox For Line Drawing Buttons
        self.fileGroupbox = QGroupBox("File")  # GroupBox for File Loading and Saving Buttons
        self.picLable = Label(self)  # Lable For showing the Image
        self.piclable_pixmap = QPixmap("loadImage.png")  # Setting Pixmap
        self.picLable.setPixmap(self.piclable_pixmap)  # setting pixmap to piclable
    def mouseMoveEvent(self, QMouseEvent):
        print(QMouseEvent.pos())

如果您想在不按下小部件的情况下检测鼠标位置,那么您必须启用 mouseTracking,这将使 mouseMoveEvent 在鼠标按下或未按下时被调用,如果您想要验证它是否未按下,您必须使用按钮()方法:

import sys

from PyQt5 import QtWidgets


class Label(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setMouseTracking(True)

    def mouseMoveEvent(self, event):
        if not event.buttons():
            print(event.pos())
        super().mouseMoveEvent(event)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = Label()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

更新:

如果子项不使用鼠标事件,则鼠标事件会从子项传播到父项,也就是说,如果子项使用了它,则父项不能使用它。所以 QLabel 正在消耗那个事件,所以 window 不会被通知,所以在这种情况下应该使用 eventFilter:

import sys

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QEvent, QObject, QPoint
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow


class HoverTracker(QObject):
    positionChanged = pyqtSignal(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, obj, event):
        if obj is self.widget and event.type() == QEvent.MouseMove:
            self.positionChanged.emit(event.pos())
        return super().eventFilter(obj, event)


class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Manual Contact Andgle")

        self.picLable = QLabel(self)
        self.picLable.setPixmap(QPixmap("loadImage.png"))

        hover_tracker = HoverTracker(self.picLable)
        hover_tracker.positionChanged.connect(self.on_position_changed)

    @pyqtSlot(QPoint)
    def on_position_changed(self, p):
        print(p)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

您可以使用 enterEvent.

每次鼠标悬停在小部件上时都会调用 Enter 事件。用event.pos()可以得到鼠标坐标。

self.label.enterEvent = lambda event: print(event.pos())