"mouseMoveEvent" 仅通过点击和拖动触发,但我需要检测它悬停在

"mouseMoveEvent" only triggers by clicking and dragging but I need to detect it hovering over

我试图在鼠标经过程序或 “MainWindow” 时为标签着色,而程序仅在我单击并拖动时更改颜色,任何其他操作比如只是点击或拖动不会触发 "mouseMoveEvent" 函数

import utils
from utils.INTERFACE_FUNCIONALITIES.FOOD_DEV import Ui_MainWindow
from utils import interface_func as i_fun
from utils import template

p = template.Product()
c = template.Client()

i_fun = i_fun.Interface()

    
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        self.show()
        self.setMouseTracking(True)
        
    def mouseMoveEvent(self, event): 
        self.rmm_lb_logo.setStyleSheet("background-color: red;") <-- TRY COLOR 
        #self.rmm_lb_logo.setText('Mouse coords: ( %d : %d )' % (event.x(), event.y()))


import sys

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    p.view()
    c.view()
    i_fun.functionalties(w)
    w.show()
    sys.exit(app.exec_())

首先,您应该 post 一个最小的工作示例。我没有你的 utils 模块。

您已经找到了第一个可能的问题,即 setMouseTracking。只有当它设置为 true 时,才会调用 mouseMoveEvent

如果您仍然没有得到 mouseMoveEvent,则这意味着其他一些小部件接受了 mouseMoveEvent

例如尝试这个最小的 working 示例:

import sys
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout

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

        self.setMouseTracking(True)

        self.label = QLabel("Mouse coordinates", parent)
        # Without this mouseMoveEvent of QLabel will be called
        # instead of mouseMoveEvent of MainWindow!
        self.label.setMouseTracking(True)

        self.setCentralWidget(self.label)

    def mouseMoveEvent(self, event):
        self.setStyleSheet("background-color: red;")
        self.label.setText('Mouse coordinates: ( %d : %d )' % (event.x(), event.y()))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

如代码中所述,QLabel 将接受 mouseMoveEvent,这意味着它不会传播到 MainWindow。 MainWindow 的 mouseMoveEvent 被调用,当移除 QLabel 并且只改变颜色或者当关闭 QLabel 上的鼠标跟踪时。

然而,关闭鼠标跟踪只是一种技巧。相反,您应该在它所属的小部件中定义 mouseMoveEvent。如果因为您想对 所有 鼠标移动做出反应而无法做到这一点,请尝试 installing an event filter on the application.

另见QMouseEvent的详细说明:

Mouse move events will occur only when a mouse button is pressed down, unless mouse tracking has been enabled with QWidget::setMouseTracking().

Qt automatically grabs the mouse when a mouse button is pressed inside a widget; the widget will continue to receive mouse events until the last mouse button is released.

A mouse event contains a special accept flag that indicates whether the receiver wants the event. You should call ignore() if the mouse event is not handled by your widget. A mouse event is propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it.

鼠标跟踪对于这种特定情况不是很有用,因为 objective 是在 window 的边界内获取鼠标事件,而不是在小部件的边界内。此外,只有在主动移动鼠标时才会收到移动事件,但是如果 window 由于任何原因(例如,另一个 window 在它上面的会隐藏或关闭)。最后,鼠标跟踪不允许知道鼠标何时真正离开小部件。

最简单的解决方案是覆盖 enterEvent() and leaveEvent():

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        
    def enterEvent(self, event):
        super().enterEvent(event)
        self.rmm_lb_logo.setStyleSheet("background-color: red;")

    def leaveEvent(self, event):
        super().leaveEvent(event)
        self.rmm_lb_logo.setStyleSheet("")