PointHandler QML Type

处理程序,用于对单个接触点做出反应。更多

Import Statement: import QtQuick
Inherits:

SinglePointHandler

属性

信号

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

详细说明

PointHandler 可用于显示触摸点或鼠标位置的反馈信息,或对指针事件做出其他反应。

当按压事件发生时,PointHandler 的每个实例都会选择一个当时尚未被 "抓取 "的点:如果按压事件发生在PointerHandler::parent 的范围内,且同一PointerHandler::parent 中没有任何同级 PointHandler 已获得该点的被动抓取,并且满足acceptedButtonsacceptedDevices 等其他约束条件,则符合条件,PointHandler 将获得被动抓取。这样,PointerHandler::parent 就像一个独占组:可以有多个 PointHandler 实例,被按下的接触点集合将在它们之间分配。每个选择了要跟踪的点的 PointHandler 都有其active 属性true 。然后,它将继续跟踪其选择的点,直至释放:point 的属性将保持最新。任何项目都可以绑定到这些属性,从而跟踪点的移动。

由于它只是一个被动抓取器,因此能够对所有移动进行独立监督。即使在检测到其他手势并发生排他性抓取时,被动抓取也不会被窃取或覆盖。

如果您的目标是对事件点进行正交监控,那么较早的替代方案是QObject::installEventFilter() ,但这从来都不是QtQuick 的内置功能:它需要一些 C++ 代码,如QQuickItem 子类。与之相比,PointHandler 的效率更高,因为在QQuickWindow 的正常事件传递过程中,只有指针事件会传递给它,而事件过滤器则需要过滤所有类型的所有 QEvents,因此会成为潜在的事件传递瓶颈。

一个可能的用例是将此处理程序添加到一个透明的项目中,该项目位于场景其他部分的顶部(通过具有较高的z 值),这样当一个点刚被按下时,它将首先传递到该项目及其处理程序,从而提供了尽早被动抓取的机会。这样一个项目(就像整个用户界面上的一块玻璃)可以很方便地成为其他项目的父项目,这些项目可以将反应反馈可视化,而反应反馈必须始终位于顶部;同样,它也可以成为弹出窗口、弹出窗口、对话框等的父项目。如果要以这种方式使用它,最好在你的 main.cpp 中使用QQmlContext::setContextProperty() 使 "玻璃窗格 "可以通过 ID 访问整个用户界面,这样其他的 Items 和 PointHandlers 就可以被重新父系化。

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 示例 - 指针处理程序

属性文档

acceptedButtons : flags

可激活此PointHandler 的鼠标按钮。

默认情况下,该属性设置为Qt.LeftButton 。可将其设置为鼠标按键的 OR 组合,并忽略按下或按住其他按键的事件。如果设置为Qt.NoButton ,则表示完全不关心按钮,并忽略来自任何设备的合成鼠标事件,因为该设备已在处理真实的eventPoint

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 对触摸点做出反应。

注: 默认情况下,当该属性为Qt.LeftButton 时,如果允许非鼠标PointerDevice (如触摸屏或图形平板电脑触控笔)生成合成鼠标事件,这些事件通常表示鼠标左键被按下,而这些事件会暂时解除PointHandler 的激活状态,因为 已在对来自设备的真实eventPoint 作出反应。声明

acceptedButtons: \c Qt.NoButton

来避免这个问题。另请参阅Qt::AA_SynthesizeMouseForUnhandledTouchEventsQt::AA_SynthesizeMouseForUnhandledTabletEvents


acceptedDevices : flags

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

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

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 : flags

如果设置了该属性,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 设置为修改器按键的 OR 组合,则表示必须按下所有这些修改器才能激活处理程序。

可用的修改器如下:

常量说明
NoModifier不允许使用任何修改键。
ShiftModifier必须按键盘上的 Shift 键。
ControlModifier必须按键盘上的 Ctrl 键。
AltModifier必须按下键盘上的 Alt 键。
MetaModifier必须按下键盘上的 Meta 键。
KeypadModifier必须按下键盘上的按键。
GroupSwitchModifier仅限 X11(除非在 Windows 上通过命令行参数激活)。必须按下键盘上的模式切换键。
KeyboardModifierMask处理程序并不关心按下的是哪个修饰符。

另请参阅 Qt::KeyboardModifier


acceptedPointerTypes : flags

可激活PointHandler 的指向工具类型(手指、触控笔、橡皮擦等)。

默认情况下,此属性设置为PointerDevice.AllPointerTypes 。如果将其设置为设备类型的 OR 组合,则会忽略来自非匹配devices 的事件:

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 Examples - Pointer Handlers(示例 - 指针处理程序)中包含一个更复杂的示例,用于使用绘图板在画布上绘图。


active : bool [read-only]

只要满足约束条件,且PointHandler 正在作出反应,它就会保持true 。这意味着,它会根据满足约束条件的eventPoints 的移动更新其属性。


cursorShape : Qt::CursorShape

activetrue 时,鼠标悬停在parent 项目上时,该属性会显示光标形状。

可用的光标形状有

  • 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.ClosedHandCursor
  • Qt.DragCopyCursor
  • Qt.DragMoveCursor
  • Qt.DragLinkCursor

默认值未设置,允许cursorparent 项目出现。可通过将该属性设置为未定义来将其重置为相同的初始状态。

注: 当该属性未设置或已设置为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此处理程序允许其抓取设置为空。
PointerHandler.ApprovesTakeOverByAnything此处理程序允许任何类型的项目或处理程序抓取。

默认值为PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything ,允许大多数接管情况,但可避免两个 PinchHandlers 争夺同一个触摸点。


margin : real

parent 项目边界以外的边距,在此范围内eventPoint 可以激活此处理程序。

默认值为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 ;也就是声明处理程序的项目。该处理程序将代表该 Item 处理事件,这意味着如果指针事件中至少有一个eventPoints 出现在该 Item 的内部,那么该指针事件就是相关的。最初target() 是相同的,但可以重新分配。

另请参阅 targetQObject::parent()。


point : handlerPoint [read-only]

当前正在处理的eventPoint 。如果当前没有正在处理的点,该对象将重置为默认值(所有坐标均为 0)。


target : real

一个属性,可以方便地保存一个要操作或显示反馈的项。与其他指针处理程序不同,PointHandler 本身不会对target 做任何操作:通常需要创建与SinglePointHandler::pointPointHandler::active 等属性的反应绑定。如果在此声明一个 Item 实例,则需要显式设置其parent ,因为PointHandler 不是一个 Item。

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


信号文档

canceled(eventPoint point)

如果该处理程序已经抓取了给定的point ,那么当抓取被其他指针处理程序或 Item 窃取时,就会发出该信号。

注: 相应的处理程序是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


© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.