我在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
}
}
}
}
答案 0 :(得分:1)
您可以在QGuiApplication上安装eventFilter
,其中所有鼠标事件都将通过。
在链接的解决方案中,我在发出信号时丢弃有关鼠标位置的信息。但是,您可以通过将传递给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)
由于您只需要查询全局鼠标位置,我建议您使用mapToGlobal或mapToItem方法。
答案 2 :(得分:0)
我相信你可以从C ++端获得光标的坐标。看看this question上的答案。问题与您的问题无关,但解决方案也有效。
在我这边,我设法通过直接调用mousePosProvider.cursorPos()
而没有任何 MouseArea 来获取全局坐标。