在QML中查询全局鼠标位置

时间:2017-11-23 08:56:01

标签: qml qtquick2 qt-quick

我在QML中编写一个小型PoC。在我的代码中的几个地方,我需要绑定到/查询全局鼠标位置(比如,场景或游戏窗口中的鼠标位置)。即使在鼠标位于我迄今已定义的MouseAreas之外的情况下也是如此。

环顾四周,唯一的方法就是让整个屏幕覆盖另一个MouseArea,最有可能启用悬停。然后我还需要处理半手动传播(悬停)事件到基础mouseAreas ..

我在这里遗漏了什么吗?这似乎是一个非常常见的情况 - 是否有更简单/更优雅的方式来实现它?

编辑: 最棘手的情况似乎是在MouseArea之外拖动。下面是一个简约的例子(它使用V-Play组件和来自derM的答案的鼠标事件间谍)。当我单击图像并在MouseArea外部拖动时,鼠标事件不再出现,因此除非下面有DropArea,否则无法更新位置。

  

MouseEventSpy取自here以回答其中一个答案。它仅被修改为包含作为信号参数的位置。

import VPlay 2.0
import QtQuick 2.0
import MouseEventSpy 1.0

GameWindow {
    id: gameWindow
    activeScene: scene
    screenWidth: 960
    screenHeight: 640

    Scene {
        id: scene
        anchors.fill: parent

        Connections {
            target: MouseEventSpy
            onMouseEventDetected: {
                console.log(x)
                console.log(y)
            }
        }

        Image {
            id: tile
            x: 118
            y: 190
            width: 200
            height: 200
            source: "../assets/vplay-logo.png"
            anchors.centerIn: parent

            Drag.active: mausA.drag.active
            Drag.dragType: Drag.Automatic

            MouseArea {
                id: mausA
                anchors.fill: parent
                drag.target: parent
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

您可以在QGuiApplication上安装eventFilter,其中所有鼠标事件都将通过。

here

描述了如何执行此操作

在链接的解决方案中,我在发出信号时丢弃有关鼠标位置的信息。但是,您可以通过将传递给QEvent - 方法的eventFilter(...)转换为QMouseEvent来轻松检索信息,并将其作为参数添加到信号中。

在链接的答案中,我将其注册为QML和C ++中的单例,以便您可以根据需要连接到信号。

正如链接答案中提供的那样,MouseEventSpy只会处理各种类型的QMouseEvents。一旦你开始拖动某些东西,就不会QMouseEvents而是QDragMoveEvents e.t.c.因此,您需要扩展filter方法,以便处理这些。

bool MouseEventSpy::eventFilter(QObject* watched, QEvent* event)
{
    QEvent::Type t = event->type();
    if (t == QEvent::MouseButtonDblClick
            || t == QEvent::MouseButtonPress
            || t == QEvent::MouseButtonRelease
            || t == QEvent::MouseMove) {
        QMouseEvent* e = static_cast<QMouseEvent*>(event);
        emit mouseEventDetected(e->x(), e->y());
    }

    if (t == QEvent::DragMove) {
        QDragMoveEvent* e = static_cast<QDragMoveEvent*>(event);
        emit mouseEventDetected(e->pos().x(), e->pos().y());
    }
    return QObject::eventFilter(watched, event);
}

然后,您可以将坐标转换为您需要的坐标(屏幕,窗口,......)

答案 1 :(得分:0)

由于您只需要查询全局鼠标位置,我建议您使用mapToGlobalmapToItem方法。

答案 2 :(得分:0)

我相信你可以从C ++端获得光标的坐标。看看this question上的答案。问题与您的问题无关,但解决方案也有效。

在我这边,我设法通过直接调用mousePosProvider.cursorPos()而没有任何 MouseArea 来获取全局坐标。