在QML中查询全局鼠标位置

在QML中查询全局鼠标位置,qml,qtquick2,qt-quick,Qml,Qtquick2,Qt Quick,我正在用QML编写一个小PoC。在代码中的几个地方,我需要绑定/查询全局鼠标位置(例如,场景或游戏窗口中的鼠标位置)。即使在我定义的鼠标区域之外的情况下 环顾四周,唯一的办法似乎是让整个屏幕覆盖另一个鼠标ea,很可能是启用了悬停。然后,我还需要处理将事件半手动传播(悬停)到底层鼠标区域的问题 我是不是遗漏了什么?这似乎是一个非常常见的情况-有没有更简单/更优雅的方法来实现它 编辑: 最有问题的情况似乎是在鼠标外拖动鼠标时。下面是一个简单的例子(它使用V-Play组件和derM的答案中的鼠标事件间

我正在用QML编写一个小PoC。在代码中的几个地方,我需要绑定/查询全局鼠标位置(例如,场景或游戏窗口中的鼠标位置)。即使在我定义的鼠标区域之外的情况下

环顾四周,唯一的办法似乎是让整个屏幕覆盖另一个鼠标ea,很可能是启用了悬停。然后,我还需要处理将事件半手动传播(悬停)到底层鼠标区域的问题

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

编辑: 最有问题的情况似乎是在鼠标外拖动鼠标时。下面是一个简单的例子(它使用V-Play组件和derM的答案中的鼠标事件间谍)。当我点击图像并拖出鼠标区域时,鼠标事件不再出现,因此除非下方有一个拖放区域,否则位置无法更新

作为对其中一个答案的响应,
MouseEventSpy
取自。仅修改为将位置作为信号参数


因为你只有几个地方需要查询全局鼠标位置,我建议你使用或方法.< /p> 我相信你可以从C++边得到光标的坐标。看看答案。这个问题与你的问题无关,但解决方案也很有效


在我这方面,我通过直接调用
mousePosProvider.cursorPos()
而不使用任何MouseArea来获得全局坐标

您可以在QGUI应用程序上安装一个
eventFilter
,所有鼠标事件都将通过该应用程序

描述了如何实现这一点

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

在链接答案中,我将它登记为QML和C++中的单件,这样就可以连接到需要的信号。
正如链接答案中提供的那样,
MouseEventSpy
将只处理各种类型的
QMouseEvents
。一旦开始拖动某个对象,将不会出现
QMouseEvents
,而是e.t.c。因此,您需要扩展筛选方法,以处理这些事件

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);
}
bool MouseEventSpy::eventFilter(QObject*监视,QEvent*事件)
{
QEvent::Type t=event->Type();
如果(t==QEvent::MouseButtonDBL单击
||t==QEvent::MouseButtonPress
||t==QEvent::MouseButtonRelease
||t==QEvent::MouseMove){
QMouseEvent*e=静态广播(事件);
发射检测到的鼠标(e->x(),e->y());
}
if(t==QEvent::DragMove){
QDragMoveEvent*e=静态_转换(事件);
发射检测到的鼠标(e->pos().x(),e->pos().y());
}
返回QObject::eventFilter(监视的,事件);
}


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

问题是,当鼠标位于当前现有鼠标区域之外时,有时我需要检查鼠标位置。在这种情况下(似乎),我没有得到任何允许我更新当前鼠标位置的鼠标移动事件。我尝试过修改您的方法,但不幸的是,它不适用于以下情况-我在屏幕上有一个鼠标earea,我按下它并开始拖动。一旦鼠标离开这个鼠标区域,鼠标移动事件就停止了,所以没有其他项目得到鼠标位置的更新。你能发布代码吗?我没有这些问题。Ofc。如果鼠标离开应用程序,它将不会接收事件。您还可以提供
MouseEventSpy
的修改代码吗?它几乎没有修改,我已将信号原型更改为:
void mouseEventDetected(int x,int y)然后:
…&&事件->自发(){QMouseEvent*me=(QMouseEvent*)事件;发出mouseEventDetected(me->globalX(),me->globalY());}
它似乎与
拖动.dragType
有关。如果被注释掉,它似乎是有效的。我将查看是否可以找到解决方案。有关修复,请参阅我的编辑。对于这种情况,您需要处理
qdragmovevent
s。我添加了到
MouseEventSpy
的链接,否则您的示例将不完整。这对于查询来说似乎非常有效,但无法绑定到它。我(添加到原始帖子中)遇到的问题是当我从MouseArea中拖出时——在这种情况下,没有收到鼠标移动事件,也没有更新当前鼠标位置的内容。
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);
}