本页内容

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实例尚未对该点获得被动抓取,同时满足其他约束条件(如acceptedButtons 、acceptedDevices 等),则该点符合条件,此时PointHandler将获得对该点的被动抓取。 通过这种方式,PointerHandler::parent 就像一个排他性组:可以存在多个 PointHandler 实例,被按下的触点集合将分配给它们。每个已选择要跟踪的点的 PointHandler 都拥有其active 属性true 。随后,它将继续跟踪所选点直至释放:point 的属性将保持最新状态。 任何 Item 都可以绑定到这些属性,从而跟随该点的移动。

由于它仅作为被动抓取器,因此能够对所有移动进行独立监视。即使检测到其他手势并发生排他性抓取,该被动抓取也不会被窃取或覆盖。

如果您的目标是对事件点进行正交监视,以前的一种替代方案是QObject::installEventFilter(),但这从来都不是QtQuick 的内置功能:它需要一些 C++ 代码,例如QQuickItem 的子类。 PointHandler 比该方法更高效,因为在QQuickWindow 中的正常事件传递过程中,只有指针事件会被传递给它;而事件过滤器需要过滤所有类型的所有 QEvent,因此可能会成为事件传递的潜在瓶颈。

一个可能的用例是将此处理程序添加到位于场景其余部分之上的透明 Item 上(通过设置较高的 `z ` 值),这样当点被新按下时,该事件将首先传递给该 Item 及其处理程序,从而有机会尽早捕获被动抓取事件。 这样的 Item(例如覆盖整个 UI 的玻璃面板)可以作为其他 Item 的便捷父项,这些 Item 用于可视化必须始终位于最上层的交互反馈;同样地,它也可以作为弹出窗口、弹出面板、对话框等的父项。 如果要以此方式使用,建议在 main.cpp 中使用 `QQmlContext::setContextProperty()` 使整个 UI 都能通过 ID 访问该“玻璃面板”,以便其他 Item 和 PointHandler 可以将其作为父项。

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 确实会启用触摸功能,从而禁用整个窗口内的原生手势识别;因此,如果您只想响应所有触摸点,但不需要流畅的原生手势体验,这可以作为一种替代方案。

另请参阅 MultiPointTouchArea 、HoverHandler 以及Qt Quick 示例 - 指针处理程序。

属性文档

acceptedButtons : flags

可触发此PointHandler 的鼠标按钮。

默认情况下,此属性设置为Qt.LeftButton 。它可以设置为鼠标按钮的“或”组合,并将忽略其他按钮被按下或按住时的事件。如果将其设置为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 (例如触摸屏或图形输入板触控笔)生成合成鼠标事件,这些事件通常表示左键被按下,并且这些事件可能会暂时停用原本正在响应该设备真实eventPoint 的PointHandler 。 声明

acceptedButtons: \c Qt.NoButton

可有效避免此问题。另请参阅Qt::AA_SynthesizeMouseForUnhandledTouchEvents 和Qt::AA_SynthesizeMouseForUnhandledTabletEvents 。

acceptedDevices : flags

能够触发此PointHandler 的指点设备类型。

默认情况下,此属性设置为PointerDevice.AllDevices 。若将其设置为设备类型的“或”组合,则会忽略来自不匹配的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 设置为修饰键的“或”组合,则意味着必须同时按下所有这些修饰键才能激活该处理程序。

可用的修饰键如下:

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

另请参阅 Qt::KeyboardModifier 。

acceptedPointerTypes : flags

可触发此PointHandler 的指点设备类型(手指、触控笔、橡皮擦等)。

默认情况下,此属性设置为PointerDevice.AllPointerTypes 。如果您将其设置为设备类型的“或”组合,则会忽略来自不匹配的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 示例——指针处理程序》中包含一个更复杂的示例,演示如何使用图形输入板在 Canvas 上绘图。

active : bool [read-only]

只要约束条件得到满足,且该PointHandler 正在响应,则该对象始终满足true 。这意味着它会根据满足约束条件的eventPoints 的运动,实时更新其属性。

cursorShape : Qt::CursorShape

当鼠标悬停在parent 项上时,如果active 的值为true ,则该属性将确定此时显示的光标形状。

可用的光标形状包括:

  • Qt.ArrowCursor
  • Qt.UpArrowCursor
  • Qt.CrossCursor
  • Qt.WaitCursor
  • Qt.IBeamCursor
  • Qt.SizeVerCursor
  • Qt.SizeHorCursor
  • Qt.SizeBDiagCursor
  • Qt.SizeFDiagCursor
  • Qt.SizeAllCursor
  • Qt.BlankCursor
  • Qt.SplitV光标
  • Qt.SplitHCursor
  • Qt.指手光标
  • Qt.禁止光标
  • Qt.什么是这个光标
  • Qt.BusyCursor
  • Qt.张开手形光标
  • Qt.紧握手形光标
  • Qt.拖拽复制光标
  • Qt.拖拽移动光标
  • Qt.DragLinkCursor

默认值未设置,这将使parent 项的cursor 显示出来。通过将该属性设置为undefined,可将其重置为初始状态。

注意:当 此属性未被设置,或已被设置为 `undefined`时 ,若读取其值,将返回 `Qt.ArrowCursor`。

另请参阅 Qt::CursorShape 、QQuickItem::cursor() 和HoverHandler::cursorShape 。

enabled : bool

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

如果PointerHandler 的parent 为disabled ,则处理程序也将被实质上禁用,即使enabled 属性仍为true 。

注意: HoverHandler 的行为有所不同:有关更多信息,请参阅其enabled 属性的文档。

grabPermissions : flags

此属性指定了当该处理程序的逻辑决定接管独占抓取时,或者当被其他处理程序请求批准接管或取消抓取时,所适用的权限。

常量描述
PointerHandler.TakeOverForbidden该处理程序既不会从任何类型的 Item 或 Handler 处获取抓取权限,也不会向其授予抓取权限。
PointerHandler.CanTakeOverFromHandlersOfSameType该处理程序可以从同一类的另一个处理程序那里接管独占抓取。
PointerHandler.CanTakeOverFromHandlersOfDifferentType该处理程序可以从任何类型的处理程序手中接管独占抓取。
PointerHandler.CanTakeOverFromItems此处理程序可以从任何类型的“项目”中获取排他性抓取权限。
PointerHandler.CanTakeOverFromAnything此处理程序可以从任何类型的项目或处理程序处获取独占抓取权限。
PointerHandler.ApprovesTakeOverByHandlersOfSameType此处理程序允许同一类的另一个处理程序获取抓取权限。
PointerHandler.ApprovesTakeOverByHandlersOfDifferentType此处理程序允许任何类型的处理程序获取抓取。
PointerHandler.ApprovesTakeOverByItems此处理程序允许任何类型的“项目”获取抓取。
PointerHandler.ApprovesCancellation该处理程序允许将其抓取设置为 null。
PointerHandler.ApprovesTakeOverByAnything此处理程序允许任何类型的 Item 或 Handler 接管抓取操作。

默认值为PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything ,这允许大多数接管场景,但可避免例如两个 PinchHandler 争夺同一触点的情况。

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 即其被声明的对象。处理程序将代表该 Item 处理事件,这意味着如果指针事件的至少一个eventPoints 发生在该 Item 的内部,则该事件与该 Item 相关。初始时,target() 与该 Item 相同,但可以被重新赋值。

另请参阅 target 和QObject::parent()。

point : handlerPoint [read-only]

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

target : real

一个可用于方便地容纳待操作的 Item 或显示反馈的属性。与其他指针处理程序不同,PointHandler 本身不会对target 执行任何操作:通常需要创建对SinglePointHandler::point 和PointHandler::active 等属性的响应式绑定。如果在此处声明一个 Item 实例,则需要显式设置其parent ,因为PointHandler 并非 Item。

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

信号文档

canceled(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 。

© 2026 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.