Search code examples
pythonpyqtmouseeventqmainwindow

Capture mouse position outside QMainWindow (without click)


I tried:

        self.installEventFilter(self)

and:

        desktop= QApplication.desktop()
        desktop.installEventFilter(self)

With:

    def eventFilter(self, source, event):
        if event.type() == QEvent.MouseMove:
            print(event.pos())
        return QMainWindow.eventFilter(self, source, event)

In QMainWindow object but nothing conclusive.
Do you have any idea?


Solution

  • Mouse events are initially handled by the window-manager, which then passes them on to whatever window is in that region of the screen. So if there are no Qt windows in that region, you won't get any events (including mouse events).

    However, it is still possible to track the cursor position via polling:

    from PyQt5 import QtCore, QtGui, QtWidgets
    # from PyQt6 import QtCore, QtGui, QtWidgets
    
    class Window(QtWidgets.QWidget):
        cursorMove = QtCore.pyqtSignal(QtCore.QPoint)
    
        def __init__(self):
            super().__init__()
            self.label = QtWidgets.QLabel()
            self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
            layout = QtWidgets.QVBoxLayout(self)
            layout.addWidget(self.label)
            self.cursorMove.connect(self.handleCursorMove)
            self.timer = QtCore.QTimer(self)
            self.timer.setInterval(50)
            self.timer.timeout.connect(self.pollCursor)
            self.timer.start()
            self._cursor = None
    
        def pollCursor(self):
            pos = QtGui.QCursor.pos()
            if pos != self._cursor:
                self._cursor = pos
                self.cursorMove.emit(pos)
    
        def handleCursorMove(self, pos):
            self.label.setText(f'x: {pos.x()}, y: {pos.y()}')
    
    if __name__ == '__main__':
    
        app = QtWidgets.QApplication(['Test'])
        window = Window()
        window.setGeometry(600, 100, 200, 200)
        window.show()
        app.exec()