To monitor the cursor position

I am trying to write code to monitor the cursor position on krita.
My ultimate goal is to write a script that reacts when the cursor enters a specific area of the Krita window.

from krita import *
from PyQt5 import QtWidgets, QtGui, QtCore

class Window(QWidget):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)

        self.installEventFilter(self)

        self.label = QLabel()
        self.label.setText("none")

        self.grid = QGridLayout()
        self.grid.addWidget(self.label, 0,0)
        self.setLayout(self.grid)

        q_win = Krita.instance().activeWindow().qwindow()

        q_win.installEventFilter(self)
        q_win.setMouseTracking(True)

    def eventFilter(self, obj, event):

        if event.type() == QEvent.MouseMove:
            pos = QCursor.pos().x()
            text = str(pos)

            self.label.setText(text)

        return False

win = Window()
win.show()

Currently, I am failing to get the cursor position at all times. I can continuously get the cursor position within a specific widget, but I cannot do it for the full krita window. If I could get the position in real time, I would not need the widget, but I only know how to use the widget, which is why I am writing it this way.
If anyone knows how to do this, please help. I am new to coding, so if you can show me the specific code, that would be great.

For these kind of things, Plugin developer tools has the Signal/Event Viewer/Debugger. Click the QMainWindow and click the Signal and Event Viewer button. Then hit play on the new window. It will show you all the signals and events that are processed in realtime and their values

In this case MouseMove is not activated, but HoverMove is

This is the first time I have heard of a hover event. Now I will manage to do what I want to do. Thank you.
The developer tools have helped me a lot as well. I am a beginner in coding and not an English speaker, so I don’t seem to be able to use many of the features.

Here is some more code that can help in learning Qt’s event system.

Note:
code uses special event hook that is installed directly to QApplication /
QCoreApplication singleton instance. It’s special because ALL events of application go through it (so better be quick in event handling or Krita will be lagged badly!)

from krita import (
        Krita,)

from PyQt5.QtCore import (
        Qt,
        QSize,
        QEvent,
        QCoreApplication)

from PyQt5.QtGui import (
        QColor,
        QPalette,
        QCursor,
        QMouseEvent,
        QTabletEvent,
        QTextCursor)

from PyQt5.QtWidgets import (
        QPlainTextEdit,)


def enum_to_human(e, enum_cls, owner):
    for name in dir(owner):
        value = getattr(owner, name)
        if isinstance(value, enum_cls):
            return name


def flag_to_human(flag, enum_cls, owner):
    pairs = list()
    for name in dir(owner):
        value = getattr(owner, name)
        if isinstance(value, enum_cls) and value > 0:
            pairs.append((value, name))
    pairs.sort(reverse=True)
    flag_value = int(flag)
    flag_list = list()
    for v, name in pairs:
        if flag_value >= int(v):
            flag_list.append(name)
            flag_value -= v
    return flag_list


class InputInfo(QPlainTextEdit):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.hook_core_app()

    def closeEvent(self, event):
        self.release_core_app()
        return super().closeEvent(event)

    def hook_core_app(self):
        """ add hook to core application. """
        q_app = QCoreApplication.instance()
        q_app.installEventFilter(self)

    def release_core_app(self):
        """ remove hook from core application. """
        q_app = QCoreApplication.instance()
        q_app.removeEventFilter(self)

    def eventFilter(self, obj, event):
        if isinstance(event, (QMouseEvent, QTabletEvent)):
            # lets do something smart!
            # Like sort big enum lists and print some text,
            # everytime mouse moves one pixel...
            modifiers = flag_to_human(event.modifiers(), Qt.KeyboardModifier, Qt)
            buttons = flag_to_human(event.buttons(), Qt.MouseButton, Qt)
            self.append_to_end(
                    f'pos = {event.pos()}\n'
                    f'modifiers = {modifiers}\n'
                    f'buttons = {buttons}\n')
        return super().eventFilter(obj, event)

    def append_to_end(self, text):
        self.moveCursor(QTextCursor.End)
        self.insertPlainText(text)


win = InputInfo()
win.show()

/AkiR

I was surprised that QCoreApplication.instance() can specify the krita window. This is better to get the cursor position more accurately. (The coordinates tend to be misaligned when using dual displays)

QMouseEvent.pos() is already translated to target widget coordinates (widget is obj argument of def eventFilter(self, obj, event)).

Note there are also QMouseEvent.globalPos() → QPoint, QMouseEvent.localPos() → QPointF, QMouseEvent.screenPos() → QPointF, QMouseEvent.windowPos() → QPointF, if you need coordinates in different space and sub pixel accuracy, and QTableEvent for pen events has things like rotation and pressure that are not available with mouse.

/AkiR