Home > front end >  SOLVED - "mouseMoveEvent" only triggers by clicking and dragging but I need to detect it h
SOLVED - "mouseMoveEvent" only triggers by clicking and dragging but I need to detect it h

Time:04-08

I'm trying to color a label whenever the mouse passes over the program or "MainWindow" and the program only changes the color if I click and drag, any other operation like just clicking or just dragging does not trigger the "mouseMoveEvent" function

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_())

CodePudding user response:

First off, you should post a minimal working example. I don't have your utils module.

You already found the first possible problem which is setMouseTracking. Only when that is set to true, will the mouseMoveEvent be called.

If you still don't get a mouseMoveEvent, then this means some other widget accepts the mouseMoveEvent.

E.g. try this minimal working example:

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_())

As annotated in the code, the QLabel will accept the mouseMoveEvent meaning it will not get propagated to MainWindow. The MainWindow's mouseMoveEvent is called, when removing the QLabel and only changing the color or when turning mouse tracking off on the QLabel.

Turning off mouse tracking, however, is only a hack. Instead, you should define the mouseMoveEvent in the widget into which it belongs. If that isn't possible because you want to react to all mouse moves, then try installing an event filter on the application.

See also the detailed description of 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.

CodePudding user response:

The mouse tracking won't be very useful for this specific situation, because the objective is to get mouse events within the boundaries of the window, not that of the widget. Also, the move event is only received when actively moving the mouse, but this will fail the result if the window becomes under the mouse for any reason (for instance, another window that was above it becomes hidden or closed). Finally, the mouse tracking doesn't allow to know when the mouse actually leaves the widget.

The simplest solution is to override the 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("")
  • Related