1

I want to get the position of mouse while it's hovering over a label. I read this but my problem is different. I need to grab the mouse position as it hovers over my label without clicking so, mouseMoveEvent doesn't help

here's my code:

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())
MarcoM
  • 1,093
  • 9
  • 25
M.H.Muhamadi
  • 139
  • 2
  • 8

2 Answers2

3

If you want to detect the mouse position without pressing on the widget then you must enable mouseTracking that will make the mouseMoveEvent invoked when the mouse is pressed or not, if you want to verify that it is not pressed you must use the buttons() method:

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

UPDATE:

Mouse events are propagated from children to parents if the children do not consume it, that is, if the child consumes it then the parent cannot consume it. So the QLabel is consuming that event so the window will not be notified, so in this case an eventFilter should be used:

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I enabled the mouse tracking but still MouseMove event only works if you press and move the mouse. – M.H.Muhamadi Mar 13 '20 at 03:42
  • You know, my problem is I made a class that inherit form Qmainwindow, and in it, I made a Qlabel, I will add my code. please take a look at it – M.H.Muhamadi Mar 13 '20 at 03:52
  • @M.H.Muhamadi If you have not provided an MRE at the time someone posts a question then do not expect it to work in your code since we do not know your code but you will first have to analyze the code that is proposed in the answer, and if it works then your code generates a new problem so an MRE is necessary and it's great that you have placed it. – eyllanesc Mar 13 '20 at 04:01
3

You can use enterEvent.

Enter event gets called everytime the mouse is over the widget. With the event.pos() you can get the mouse coordinates.

self.label.enterEvent = lambda event: print(event.pos())
sabz
  • 460
  • 1
  • 4
  • 10