Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt5 Mouse Tracking Over QLabel Object

I am using PyQt5 to create an application. The application has a MainWindow with several widgets. One of the widgets is a QLabel object that displays a video. I want to track the cursor and display the cursor coordinates as I mouse over the video when I check a radio button.

I created a MouseTracking class that I’m passing the QLabel object into as window. I have verified that the passed into the class by printing its geometry. But I’m somehow not associating the mouse tracking to window. Here is the code for the MouseTracking class. What am I doing wrong?

class MouseTracker(QLabel):
    def __init__(self, window):
        super().__init__(window)
        self.window = window
        self.window.setMouseTracking(True)
        self.initUI()

    def initUI(self):
        self.label = QLabel(self)
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setStyleSheet('background-color: white; border: 1px solid black')
        self.show()

    def mouseMoveEvent(self, event):
        x = event.x()
        y = event.y()
        print("X, Y = ", x, y)
        self.label.setGeometry(x+30, y-15, 90, 40)
        self.label.setText('(%d, %d)' % (x, y))
like image 327
slalomchip Avatar asked Oct 28 '25 09:10

slalomchip


1 Answers

In your code you have enabled the mouseTracking property of the "window" but you are monitoring the mouseMoveEvent method of the MouseTracker which is incorrect. If you want to track the events of a widget without overriding any method then you must use an event filter.

In the following example I try to implement your application based on your description, for example the green QLabel represents the QLabel that the video shows. Considering the above, the solution is as follows:

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

enter image description here

like image 170
eyllanesc Avatar answered Oct 29 '25 23:10

eyllanesc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!