3

この問題は Windows で発生しますが、Linux では発生しません。他のプラットフォームは試していません。

QCursorマウスの位置を設定するために使用するカスタム クラス (以下のコード) があります。

問題は次のコード ( 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.');
        }
    }
}

問題を再現する手順:

  1. ウィンドウ上でマウス ダウンします。カーソルが画面の左上に移動し、onExited発火します。
  2. マウス ボタンを離します。カーソルがウィンドウの中央にジャンプします。
  3. ウィンドウの外にマウスを移動します。

onExitedユーザーがウィンドウの外にマウスを移動すると、もう一度起動する必要がありますが、起動しません。私ができる方法はありますか

  1. 発火させるか、
  2. そうでなければ、マウスがマウス領域の外に移動したことを検出しますか?

onPositionChangedそれでも発火しますが、これを使用して、マウスがMouseArea離れたときではなく、の端に近づいたことを検出することしかできません。

手動で特殊なケースの位置チェックを行う方法として、上にグローバルをオーバーレイし、MouseAreaすべてのイベントを通過させようとしましたが、ホバー イベントを通過させることができませんでした。


マウス位置を設定するクラス:

#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);
}

このクラスをメイン関数で QML の型として登録します。

int main(int argc, char *argv[]) {
    // ...
    qmlRegisterType<MouseHelper>("io.github.myProject.utilities.mousehelper",
                                 1, 0, "MouseHelper");
}

その後、QML にインポートして使用できます。

4

1 に答える 1

5

問題の回避策として、タイマーを使用してマウス カーソルの位置をリセットできます。

QMLのいずれかで:

MouseArea {
...
    Timer {
        id: timer
        interval: 10
        repeat: false
        onTriggered: {
            mouseHelper.setCursorPosition(mouseArea.p.x, mouseArea.p.y)
        }
    }
    
    onReleased: {
        timer.start()
    }
...
}

または、MouseHelper クラスで:

#include <QTimer>
...
void MouseHelper::setCursorPosition(int x, int y) {
    QTimer::singleShot(10, this, [x, y]() { QCursor::setPos(x, y); });
}

タイマーの間隔が小さすぎない場合、これは私にとってはうまくいきます。

于 2020-08-24T06:49:43.647 に答える