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