This issue happens on Windows, but not on Linux. I haven't tried any other platforms.
I have a custom class (code below) that uses QCursor
to set the mouse position.
The issue is with the following code (repo):
import QtQuick 2.15
import QtQuick.Window 2.15
// Custom C++ class, implementation below
import io.github.myProject.utilities.mousehelper 1.0
Window {
visible: true
width: 800
height: 600
MouseHelper { id: mouseHelper }
MouseArea {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
property var p
onPressed: {
p = mouseArea.mapToGlobal(
mouseArea.width * 0.5, mouseArea.height * 0.5);
mouseHelper.setCursorPosition(0, 0);
}
onReleased: {
mouseHelper.setCursorPosition(p.x, p.y);
}
onExited: {
console.log('This should happen twice, but it only happens once.');
}
}
}
Steps to reproduce the issue:
onExited
will fire.onExited
should fire a second time when the user moves the mouse out of the window, but it doesn't. Is there some way I can either
onPositionChanged
still fires, but I can only use this to detect when the mouse is close to the edge of the MouseArea
, not when it has left.
I tried overlaying a global MouseArea
on top and passing all events through as a way to do some manual special-case position checking, but I couldn't pass hover events through.
The class for setting the mouse position:
#ifndef MOUSEHELPER_H
#define MOUSEHELPER_H
#include <QObject>
#include <QCursor>
class MouseHelper : public QObject {
Q_OBJECT
public:
explicit MouseHelper(QObject *parent = nullptr);
Q_INVOKABLE void setCursorPosition(int x, int y);
signals:
public slots:
};
#endif // MOUSEHELPER_H
#include "mousehelper.h"
#include <QGuiApplication>
MouseHelper::MouseHelper(QObject *parent) : QObject(parent) {}
void MouseHelper::setCursorPosition(int x, int y) {
QCursor::setPos(x, y);
}
I register this class as a type with QML in my main function:
int main(int argc, char *argv[]) {
// ...
qmlRegisterType<MouseHelper>("io.github.myProject.utilities.mousehelper",
1, 0, "MouseHelper");
}
I can then import it in QML and use it.
As a workaround for your problem you can use a Timer to reset the position of the mouse cursor.
Either in QML:
MouseArea {
...
Timer {
id: timer
interval: 10
repeat: false
onTriggered: {
mouseHelper.setCursorPosition(mouseArea.p.x, mouseArea.p.y)
}
}
onReleased: {
timer.start()
}
...
}
Or in your MouseHelper class:
#include <QTimer>
...
void MouseHelper::setCursorPosition(int x, int y) {
QTimer::singleShot(10, this, [x, y]() { QCursor::setPos(x, y); });
}
This works for me if the interval of the timer is not too small.