QML 鼠标在鼠标区域中的绝对位置

QML mouse absolute position in MouseArea

本文关键字:鼠标 位置 区域 QML      更新时间:2023-09-26

如何从鼠标区域获取鼠标绝对位置?我需要让它显示弹出窗口的正确位置

Item {
    Menu {
        id: menu
        MenuItem {
            onTriggered: {
               // Need Mouse absolute position
            }
        }
    }
    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: {
            menu.popup()
        }
    }

简答

  • 映射到/从另一个项目映射:mapToItemmapFromItem
  • 映射到全局/从全局映射(从Qt 5.7开始):mapToGlobalmapFromGlobal
    onClicked: {
        var positionInPopup = mapToItem(popup, mouse.x, mouse.y)
    }

更长的答案

就像 indalive 所暗示的那样,映射坐标的首选方法是使用 mapToItem ,可用于任何项目。它将坐标(和大小)从当前项目坐标系(如果未另行指定)转换为另一个项目坐标系。而mapFromItem对手自然会反其道而行之。

从Qt 5.7开始,您还有mapToGlobal,它将为您提供系统/屏幕引用中的坐标。

MouseArea {
    // ...
    onPositionChanged: {
        var positionInRoot = mapToItem(root, mouse.x, mouse.y)
        var positionInWindow = mapToItem(window.contentItem, mouse.x, mouse.y)
        var globalPosition = mapToGlobal(mouse.x, mouse.y)
        console.log("For root: " + positionInRoot )
        console.log("For window: " + positionInWindow)
        console.log("For system: " + globalPosition)
    }
}

给定上面的例子,并且...

  • 您的MouseArea接近root,离Window左上角稍远
  • 窗口本身距离屏幕最左侧为 1000px+

。您将看到:

对于根: QPointF(10, 0)

窗口用: QPointF(150, 100)

系统适用: QPointF(1230, 120)

Window类型的注意事项

当与Window(QML类型)进行转换时,您需要使用其contentItem属性,因为mapTo/From仅适用于Item

您可能已经找到了答案,但是我将把我的解决方案放在这里,供其他寻找相同事物的人使用。

下面的函数将找到鼠标区域的绝对位置。然后您可以相应地添加鼠标X和鼠标Y以获取鼠标位置。

Item {
  Menu {
    id: menu
    MenuItem {
      onTriggered: {
        var absolutePos = getAbsolutePosition(source);
        // Need Mouse absolute position
      }
    }
  }
  MouseArea {
    id: mouseArea
    anchors.fill: parent
    onClicked: {
      menu.popup()
    }
  }
  function getAbsolutePosition(node) {
      var returnPos = {};
      returnPos.x = 0;
      returnPos.y = 0;
      if(node !== undefined && node !== null) {
          var parentValue = getAbsolutePosition(node.parent);
          returnPos.x = parentValue.x + node.x;
          returnPos.y = parentValue.y + node.y;
      }
      return returnPos;
  }
}
在这种情况下,

mouseArea 填充他的父项(anchors.fill:parent),因此 mouseArea.mouseX 和 mouseArea.mouseY 是绝对的鼠标位置。对于相对位置,您应该使用 mapFromItem 和 mapToItem 函数 http://doc.qt.io/qt-5/qml-qtquick-item.html#mapToItem-method

如果您查看鼠标区域(http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-mousearea.html#onClicked-signal )中 onClicked 信号的文档,您将获得一个名为 mouse 的 MouseEvent 参数。使用 MouseEvent 对象 (http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-mouseevent.html),您可以使用

mouse.x
mouse.y