PointHandler QML 类型

用于响应单个触摸点的处理器。 更多信息...

导入声明import QtQuick
继承

SinglePointHandler

属性

信号

  • canceled(eventPoint point)
  • grabChanged(PointerDevice::GrabTransition transition, eventPoint point)

详细说明

PointHandler 可以用来显示触摸点或鼠标位置的相关反馈,或者其他响应用户操作的事件。

当按下事件发生时,每个 PointHandler 实例选择一个尚未被“占用”的单一点:如果按下事件发生在 PointerHandler::parent 的范围内,并且同一 PointerHandler::parent 中的其他 PointHandler 尚未在该点获得被动抓取,并且其他如 acceptedButtonsacceptedDevices 等约束条件得到满足,它就有资格 acquire。此时,PointHandler 获得了一个被动抓取。这样,PointerHandler::parent 就像一个独占组:可以有多个 PointHandler 实例,而按下的触摸点将分布在这它们之间。每个选择了一个点进行追踪的 PointHandler,它自己的 active 属性设置为 true。然后它继续追踪所选的点,直到释放:点的相关属性将会更新。任何项都可以绑定到这些属性上,并以此来追踪点的移动。

因为它只是一个被动抓取器,所以它有能力独立地监督所有动作。即使在检测到其他手势和获得独占抓取时,被动抓取也不能被偷走或改写。

如果您目标是对事件点的正交监视,一个更早的替代方案是QObject::installEventFilter(),但这从来没有是QtQuick的内建功能:它需要一些C++代码,例如一个QQuickItem子类。PointHandler的效率更高,因为它只接收在QQuickWindow的普通事件传输过程中的指针事件;而事件过滤器需要过滤所有类型的QEvents,因此它可能成为事件传输的潜在瓶颈。

一个可能的用例是将此处理程序添加到位于场景顶部(通过有一个高的-z值)的透明Item中,以便当新压下一个点时,它将首先传递给该Item及其处理程序,从而为最早积极放置提供机会。这样的项目(如覆盖整个UI的玻璃面板)可以方便地作为其他项目的父项;同样,它也可以成为弹出窗口、弹出、对话框等的父项。如果要将它用于这种方式,对于main.cpp来说,使用QQmlContext::setContextProperty()将“玻璃”面以ID的方式提供给整个UI是有帮助的,这样其他项目就可以重新分配给它。

import QtQuick

Window {
    width: 480
    height: 320
    visible: true

    Item {
        id: glassPane
        z: 10000
        anchors.fill: parent

        PointHandler {
            id: handler
            acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad
            target: Rectangle {
                parent: glassPane
                color: "red"
                visible: handler.active
                x: handler.point.position.x - width / 2
                y: handler.point.position.y - height / 2
                width: 20; height: width; radius: width / 2
            }
        }
    }
}

与其他输入处理程序一样,PointHandler有一个target属性,可以将其用作放置点跟踪项的便捷位置;但PointHandler不会以任何方式自动操作target项。您需要使用绑定让它对point做出反应。

注意:在macOS上,PointHandler默认不会对多指触控板做出反应,尽管它可以对按下的点(鼠标位置)做出反应。这是因为macOS可以提供原生手势识别或原始触控点,但不能同时提供。我们更愿意在PinchHandler中使用原生手势事件,所以我们不想通过启用触摸来禁用它。但是MultiPointTouchArea启用了触摸,因此禁用了整个窗口中的原生手势识别;所以,如果您只想对所有触控点做出反应但不需要平滑的原生手势体验,这是一个替代方案。

另请参阅:MultiPointTouchAreaHoverHandlerQt Quick示例 - Pointer Handlers

属性文档

acceptedButtons : 标志

可以激活此PointHandler的鼠标按钮。

默认情况下,该属性设置为 Qt.LeftButton。可以将其设置为鼠标按钮的或组合,并忽略其中包含其他按钮按下或保持的事件。

import QtQuick

Item {
    width: 480; height: 320

    Rectangle {
        color: handler.active ? "tomato" : "wheat"
        x: handler.point.position.x - width / 2
        y: handler.point.position.y - height / 2
        width: 20; height: width; radius: width / 2
    }

    PointHandler {
        id: handler
        acceptedButtons: Qt.MiddleButton | Qt.RightButton
    }
}

注意:在触摸屏上没有按钮,因此该属性不会阻止PointHandler对触控点做出反应。


acceptedDevices : 标志

可以激活此PointHandler的指向设备类型。

默认情况下,该属性设置为PointerDevice.AllDevices。如果将其设置为设备类型的或组合,将忽略来自不匹配设备的事件。

PointHandler {
    id: handler
    acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad
    target: Rectangle {
        parent: glassPane
        color: "red"
        visible: handler.active
        x: handler.point.position.x - width / 2
        y: handler.point.position.y - height / 2
        width: 20; height: width; radius: width / 2
    }
}

acceptedModifiers : 标志

如果设置了此属性,PointHandler 需要按下给定的键盘修饰符才能对 PointerEvents 做出反应,否则将其忽略。

如果此属性设置为 Qt.KeyboardModifierMask(默认值),则 PointHandler 忽略修饰键。

例如,一个 Item 可以有两个处理程序,其中一个只有在按下所需的键盘修饰符时才启用

import QtQuick

Item {
    id: feedbackPane
    width: 480; height: 320

    PointHandler {
        id: control
        acceptedModifiers: Qt.ControlModifier
        cursorShape: Qt.PointingHandCursor
        target: Rectangle {
            parent: feedbackPane
            color: control.active ? "indianred" : "khaki"
            x: control.point.position.x - width / 2
            y: control.point.position.y - height / 2
            width: 20; height: width; radius: width / 2
        }
    }

    PointHandler {
        id: shift
        acceptedModifiers: Qt.ShiftModifier | Qt.MetaModifier
        cursorShape: Qt.CrossCursor
        target: Rectangle {
            parent: feedbackPane
            color: shift.active ? "darkslateblue" : "lightseagreen"
            x: shift.point.position.x - width / 2
            y: shift.point.position.y - height / 2
            width: 30; height: width; radius: width / 2
        }
    }
}

如果您将 acceptedModifiers 设置为修饰符键的按位或组合,则意味着必须 全部 按下这些修饰符才能激活处理程序。

可用的修饰符如下

常量描述
NoModifier不允许任何修饰键。
ShiftModifier必须按下键盘上的 Shift 键。
ControlModifier必须按下键盘上的 Ctrl 键。
AltModifier必须按下键盘上的 Alt 键。
MetaModifier必须按下键盘上的 Meta 键。
KeypadModifier必须按下键盘旁边的数字键。
GroupSwitchModifier仅适用于 X11(除非在 Windows 上通过命令行参数激活)。必须按下键盘上的 Mode_switch 键。
KeyboardModifierMask处理器不关心按下哪些修饰符。

另请参阅Qt::KeyboardModifier


acceptedPointerTypes : flags

可以激活此 PointHandler 的指向设备类型(手指、笔、橡皮擦等)。

默认情况下,此属性设置为 PointerDevice.AllPointerTypes。如果将其设置为设备类型的按位或组合,则将忽略来自不匹配的 设备 的事件

import QtQuick

Canvas {
    id: canvas
    width: 800
    height: 600
    antialiasing: true
    renderTarget: Canvas.FramebufferObject
    property var points: []
    onPaint: {
        if (points.length < 2)
            return
        var ctx = canvas.getContext('2d');
        ctx.save()
        ctx.strokeStyle = stylusHandler.active ? "blue" : "white"
        ctx.lineCap = "round"
        ctx.beginPath()
        ctx.moveTo(points[0].x, points[0].y)
        for (var i = 1; i < points.length; i++)
            ctx.lineTo(points[i].x, points[i].y)
        ctx.lineWidth = 3
        ctx.stroke()
        points = points.slice(points.length - 2, 1)
        ctx.restore()
    }

    PointHandler {
        id: stylusHandler
        acceptedPointerTypes: PointerDevice.Pen
        onPointChanged: {
            canvas.points.push(point.position)
            canvas.requestPaint()
        }
    }

    PointHandler {
        id: eraserHandler
        acceptedPointerTypes: PointerDevice.Eraser
        onPointChanged: {
            canvas.points.push(point.position)
            canvas.requestPaint()
        }
    }

    Rectangle {
        width: 10; height: 10
        color: stylusHandler.active ? "green" : eraserHandler.active ? "red" : "beige"
    }
}

Qt Quick 示例 - 指针处理程序 包含在画布上使用绘图板绘制的一个更复杂的示例。


active : bool [只读]

每当约束条件满足并且此 PointHandler 正在反应时,它将保持为 true。这意味着它会根据满足约束条件的 eventPoints 的运动保持其属性最新。


cursorShape : Qt::CursorShape

此属性保存当鼠标在 parent 元素上悬停且 activetrue 时将显示的光标形状。

可用的光标形状如下

  • Qt.ArrowCursor
  • Qt.UpArrowCursor
  • Qt.CrossCursor
  • Qt.WaitCursor
  • Qt.IBeamCursor
  • Qt.SizeVerCursor
  • Qt.SizeHorCursor
  • Qt.SizeBDiagCursor
  • Qt.SizeFDiagCursor
  • Qt.SizeAllCursor
  • Qt.BlankCursor
  • Qt.SplitVCursor
  • Qt.SplitHCursor
  • Qt.PointingHandCursor
  • Qt.ForbiddenCursor
  • Qt.WhatsThisCursor
  • Qt.BusyCursor
  • Qt.OpenHandCursor
  • Qt.CloseHandCursor
  • Qt.DragCopyCursor
  • Qt.DragMoveCursor
  • Qt.DragLinkCursor

默认值未设置,允许 cursor 显示在 parent 元素上。可以通过将其设置为未定义来将此属性重置为相同的初始条件。

注意:当此属性未设置或已设置为 undefined 时,读取它将返回 Qt.ArrowCursor

另请参阅Qt::CursorShapeQQuickItem::cursor() 和 HoverHandler::cursorShape


enabled : bool

如果禁用 PointerHandler,它将拒绝所有事件且不会发出任何信号。


grabPermissions : flags

该属性指定了在不同情况下处理程序需要控制独占抓取的权限,例如当处理程序逻辑决定接管独占抓取,或者当其他处理程序请求审批抓取接管或取消时。

常量描述
PointerHandler.TakeOverForbidden此处理程序既不从任何类型的项或处理程序那里获取抓取权限,也不给予它们抓取权限。
PointerHandler.CanTakeOverFromHandlersOfSameType此处理程序可以从同一类的其他处理程序那里接管独占抓取。
PointerHandler.CanTakeOverFromHandlersOfDifferentType此处理程序可以从任何类型的处理程序那里接管独占抓取。
PointerHandler.CanTakeOverFromItems此处理程序可以从任何类型的项那里接管独占抓取。
PointerHandler.CanTakeOverFromAnything此处理程序可以从任何类型的项或处理程序那里接管独占抓取。
PointerHandler.ApprovesTakeOverByHandlersOfSameType此处理程序允许同一类的其他处理程序进行抓取。
PointerHandler.ApprovesTakeOverByHandlersOfDifferentType此处理程序允许任何类型的处理程序进行抓取。
PointerHandler.ApprovesTakeOverByItems此处理程序允许任何类型的项进行抓取。
PointerHandler.ApprovesCancellation此处理程序将允许其抓取设置为null。
PointerHandler.ApprovesTakeOverByAnything此处理程序允许任何类型的项或处理程序进行抓取。

默认值为 PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything,允许大多数接管场景,但避免了例如两个PinchHandlers为相同的触摸点斗争的情况。


margin : real

在父项边界之外的空白空间内,一个事件点可以激活这个处理程序。

默认值为 0

import QtQuick

Item {
    width: 480; height: 320

    Rectangle {
        anchors.fill: handlingContainer
        anchors.margins: -handler.margin
        color: "beige"
    }

    Rectangle {
        id: handlingContainer
        width: 200; height: 200
        anchors.centerIn: parent
        border.color: "green"
        color: handler.active ? "lightsteelblue" : "khaki"

        Text {
            text: "X"
            x: handler.point.position.x - width / 2
            y: handler.point.position.y - height / 2
            visible: handler.active
        }

        PointHandler {
            id: handler
            margin: 30
        }
    }

}

parent : Item

作为处理程序作用域的Item;声明的项。处理程序将代表此项处理事件,这意味着如果至少有一个事件点在此项内部发生,则指针事件相关。初始情况下,target() 是相同的,但可以重新分配。

另请参阅targetQObject::parent


point : handlerPoint [只读]

目前正在处理的事件点。


target : real

一个可以方便地存储要操作或显示反馈的项的属性。与其他Pointer Handlers不同,PointHandler自身不会对target做任何事情:您通常需要创建响应式绑定到如SinglePointHandler::pointPointHandler::active等属性。如果您在此声明项实例,需要显式设置其parent,因为PointHandler不是一个Item

默认情况下,它与parent相同,即处理程序声明的项。


信号文档

已取消(eventPoint point)

如果此处理程序已经捕获了指定的point,当该捕获被不同的指针处理程序或项目窃取时,将发出此信号。

注意:相应的处理程序是onCanceled


grabChanged(PointerDevice::GrabTransition transition, eventPoint point)

当此处理程序的抓取以某种方式更改时,将发出此信号。

transition(动词)说明发生了什么。 point(对象)是已捕获或取消捕获的点。

transition的有效值包括:

常量描述
PointerDevice.GrabExclusive此处理程序已承担对point的主要处理责任。
PointerDevice.UngrabExclusive此处理程序已放弃其先前的独家捕获。
PointerDevice.CancelGrabExclusive此处理程序的独家捕获已接管或取消。
PointerDevice.GrabPassive此处理程序已获取被动捕获,以监视point
PointerDevice.UngrabPassive此处理程序已放弃其先前的被动捕获。
PointerDevice.CancelGrabPassive此处理程序的先前被动捕获异常终止。

注意:相应的处理程序是onGrabChanged


© 2024 Qt公司。在此项文件中包含的文档贡献是各自所有者的版权。提供的文档按<%= 'GNU Free Documentation License version 1.3' %>的条款获得许可,该条款由自由软件基金会发布。Qt和相应的标志是芬兰和/或其他国家的Qt公司的商标。所有其他商标均为各自所有者的财产。