PinchHandler QML Type
捏合手势的处理程序。更多...
| Import Statement: | import QtQuick |
| Inherits: |
属性
- acceptedDevices : flags
- acceptedModifiers : flags
- acceptedPointerTypes : flags
- active : bool
- activeRotation : real
- activeScale : real
- activeTranslation : point
- centroid : QtQuick::handlerPoint
- cursorShape : Qt::CursorShape
- dragThreshold : int
- enabled : bool
- grabPermissions : flags
- margin : real
- parent : Item
- persistentRotation : real
- persistentScale : real
- persistentTranslation : point
- rotationAxis
- rotationAxis.activeValue : real
- rotationAxis.enabled : bool
- rotationAxis.maximum : real
- rotationAxis.minimum : real
- scaleAxis
- scaleAxis.activeValue : real
- scaleAxis.enabled : bool
- scaleAxis.maximum : real
- scaleAxis.minimum : real
- target : Item
- xAxis
- xAxis.activeValue : real
- xAxis.enabled : bool
- xAxis.maximum : real
- xAxis.minimum : real
- yAxis
- yAxis.activeValue : real
- yAxis.enabled : bool
- yAxis.maximum : real
- yAxis.minimum : real
信号
- canceled(eventPoint point)
- grabChanged(PointerDevice::GrabTransition transition, eventPoint point)
- rotationChanged(qreal delta)
- scaleChanged(qreal delta)
- translationChanged(QVector2D delta)
详细描述
PinchHandler 是一个处理程序,用于解析多指手势,从而交互式地旋转、缩放和拖动一个 Item。与其他输入处理程序一样,它默认即具备完整功能,并操作其target ——即声明该处理程序的那个 Item。
import QtQuick
Rectangle {
width: 400
height: 300
color: "lightsteelblue"
PinchHandler { }
}它具有用于限制拖动、旋转和缩放范围的属性。
如果它声明在一个 Item 内,但被赋予了不同的target ,则它会在外部 Item 的边界内处理事件,但操作的却是target 中的 Item:
import QtQuick
Item {
width: 640
height: 480
Rectangle {
id: map
color: "aqua"
width: 400
height: 300
}
PinchHandler {
target: map
}
}第三种用法是将 `target ` 设置为 `null `,并通过其他方式响应属性变化:
import QtQuick
Window {
width: 320; height: 240
visible: true
title: handler.persistentRotation.toFixed(1) + "° " +
handler.persistentTranslation.x.toFixed(1) + ", " +
handler.persistentTranslation.y.toFixed(1) + " " +
(handler.persistentScale * 100).toFixed(1) + "%"
PinchHandler {
id: handler
target: null
persistentScale: 0.25
onTranslationChanged: (delta) => {
image.x -= delta.x
image.y -= delta.y
}
}
Image {
id: image
source: "images/album-cover.jpg"
scale: handler.persistentScale
x: -600; y: -450
}
}
注意: 当按压的手指数量在minimumPointCount 到maximumPointCount 之间(含边界值)时,捏合操作 才开始。在此之前,PinchHandler会跟踪所有按压手指的位置,但如果手指数量不符合要求,它不会缩放或旋转其target ,且active 属性仍保持为false 。
另请参阅 PinchArea 、QPointerEvent::pointCount()、QNativeGestureEvent::fingerCount() 以及Qt Quick 示例——指针处理程序。
属性文档
acceptedDevices : flags
可以触发此指针处理程序的指针设备类型。
默认情况下,此属性设置为PointerDevice.AllDevices 。如果将其设置为设备类型的“或”组合,则会忽略来自不匹配设备的事件。
例如,可以通过两个处理程序使某个控件对鼠标和触控笔的点击做出一种响应,对触摸屏的轻触做出另一种响应:
Item {
TapHandler {
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
onTapped: console.log("clicked")
}
TapHandler {
acceptedDevices: PointerDevice.TouchScreen
onTapped: console.log("tapped")
}
}注意:并非 所有平台目前都能区分鼠标和触控板;而在能够区分的平台上,您通常希望鼠标和触控板的行为保持一致。
acceptedModifiers : flags
如果设置了此属性,则必须按下指定的键盘修饰键,指针事件才会生效;否则将忽略这些修饰键。
如果此属性设置为Qt.KeyboardModifierMask (默认值),则PointerHandler 将忽略修饰键。
例如,一个Item 可以包含两个同类型的处理程序,其中一个仅在按下所需的键盘修饰键时才被启用:
Item {
TapHandler {
acceptedModifiers: Qt.ControlModifier
onTapped: console.log("control-tapped")
}
TapHandler {
acceptedModifiers: Qt.NoModifier
onTapped: console.log("tapped")
}
}若将acceptedModifiers 设置为修饰键的“或”组合,则意味着必须按下所有这些修饰键才能激活该处理程序:
Item {
TapHandler {
acceptedModifiers: Qt.ControlModifier | Qt.AltModifier | Qt.ShiftModifier
onTapped: console.log("control-alt-shift-tapped")
}
}可用的修饰键如下:
| 常量 | 描述 |
|---|---|
NoModifier | 不允许使用任何修饰键。 |
ShiftModifier | 必须按下键盘上的 Shift 键。 |
ControlModifier | 必须按下键盘上的 Ctrl 键。 |
AltModifier | 必须按下键盘上的 Alt 键。 |
MetaModifier | 必须按下键盘上的 Meta 键。 |
KeypadModifier | 必须按下数字小键盘上的某个按键。 |
GroupSwitchModifier | 仅限 X11(除非在 Windows 上通过命令行参数激活)。必须按下键盘上的 Mode_switch 键。 |
KeyboardModifierMask | 处理程序不关心按下了哪些修饰键。 |
如果您需要比通过组合多个处理程序和多个修饰符标志所能实现的更复杂的行为,可以在 JavaScript 代码中检查修饰键:
Item {
TapHandler {
onTapped:
switch (point.modifiers) {
case Qt.ControlModifier | Qt.AltModifier:
console.log("CTRL+ALT");
break;
case Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier:
console.log("CTRL+META+ALT");
break;
default:
console.log("other modifiers", point.modifiers);
break;
}
}
}另请参阅 Qt::KeyboardModifier 。
acceptedPointerTypes : flags
可触发此“指针处理程序”的指针设备类型(手指、触控笔、橡皮擦等)。
默认情况下,此属性设置为PointerDevice.AllPointerTypes 。若将其设置为设备类型的“或”组合,则会忽略来自不匹配的devices 的事件。
例如,可以通过两个处理程序使某个控件以某种方式响应鼠标、触摸和触控笔的点击,但若在图形平板上使用橡皮擦工具轻点该控件,则将其删除:
Rectangle {
id: rect
TapHandler {
acceptedPointerTypes: PointerDevice.Generic | PointerDevice.Finger | PointerDevice.Pen
onTapped: console.log("clicked")
}
TapHandler {
acceptedPointerTypes: PointerDevice.Eraser
onTapped: rect.destroy()
}
}active : bool [read-only]
当所有约束条件(特别是minimumPointCount 和maximumPointCount )均得到满足,且正在操作target (如有)时,该属性即为true 。
activeRotation : real [read-only]
捏合手势的旋转角度(单位为度),正值表示顺时针方向。手势开始时,该值为0 。如果target 不为空,该值将自动添加到其rotation 中。否则,可以使用绑定对该值进行任意操作。
另请参阅 QtQuick::PinchHandler::rotationAxis.activeValue 。
activeScale : real [read-only]
执行捏合手势时的缩放因子。该值在手势开始时为 1.0,随着触点向外张开而增大,随着触点向内靠拢而减小。如果 `target ` 不为空,其 `scale ` 将自动乘以该值。否则,可通过绑定对该值进行任意操作。
另请参阅 QtQuick::PinchHandler::scaleAxis.activeValue 。
activeTranslation : point [read-only]
在执行捏合手势时,点群的平移量。手势开始时该值为0, 0 ,随着eventPoint(s) 向下和向右拖动而增加。手势结束后,该值保持不变;当下一个捏合手势开始时,它会重新设为0, 0 。
注意:在 某些触控板上 (例如 macOS 触控板),原生手势不会生成任何平移值,因此该属性将保持为(0, 0) 。
centroid : QtQuick::handlerPoint [read-only]
位于当前被按下的触点正中间的一个点。target 将围绕该点进行旋转。
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 。
dragThreshold : int
用户必须将eventPoint 拖动多少像素,该操作才会被视为拖动手势。
默认值取决于平台和屏幕分辨率。将其设置为 undefined 可将其重置为默认值。不同处理程序在拖动手势开始时的行为各不相同。
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 可以在该区域内触发此处理程序。例如,在PinchHandler 中,当target 同时也是parent 时,将此距离设置为至少相当于普通用户手指宽度的一半是很有用的,这样即使parent 被缩放至非常小的尺寸,仍可执行捏合手势。 或者,如果将基于TapHandler 的按钮放置在屏幕边缘附近,则可以利用这一点来符合菲茨定律:即使按钮在视觉上距离屏幕边缘有几像素的间隔,也能对屏幕边缘的鼠标点击做出响应。
默认值为 0。

parent : Item
Item ,即处理程序的作用域;即声明该处理程序的 Item。处理程序将代表该 Item 处理事件,这意味着,如果指针事件的至少一个eventPoints 发生在该 Item 的内部,则该事件与该 Item 相关。初始时,target() 与该 Item 相同,但可以重新赋值。
另请参阅 target 以及QObject::parent()。
persistentRotation : real
如果target 不为空,则对其应用此旋转。否则,可通过绑定对该值进行任意操作。在执行捏合手势期间,activeRotation 会持续被追加;手势结束后,该值保持不变;当下一个捏合手势开始时,activeRotation 将再次对其进行修改。
可以设置此属性,以此将基面旋转与通过其他方式(例如由另一个处理程序)设定的旋转进行同步。如果直接设置此属性,activeRotation 不会改变,并且会触发rotationChanged(0) 事件。
persistentScale : real
如果该值不为空,则target 将自动设置此缩放因子。否则,可通过绑定对该值进行任意操作。在执行捏合手势期间,该值会持续与activeScale 相乘;手势结束后,该值保持不变;当下一个捏合手势开始时,该值将再次与activeScale 相乘。
可以设置此属性,以此将基准缩放比例与其他方式(例如由另一个处理程序)设定的缩放比例进行同步。若直接设置此属性,activeScale 不会发生变化,并将触发scaleChanged(1) 事件。
persistentTranslation : point
如果target 不是null ,则应用此转换。否则,可通过绑定对该值进行任意操作。在执行捏合手势期间,activeTranslation 会持续被添加到该值中;手势结束后,该值保持不变。
可以设置此属性,以此将基准平移值与通过其他方式(例如由另一个处理程序)设置的平移值进行同步。若直接设置此属性,activeTranslation 不会改变,且会触发translationChanged({0, 0}) 事件。
注意:在 某些触控板上 (例如 macOS 触控板),原生手势不会生成任何平移值,且该属性将保持为 `(0, 0)`。
rotationAxis group
rotationAxis.activeValue : real [read-only]
rotationAxis.enabled : bool
rotationAxis.maximum : real
rotationAxis.minimum : real
rotationAxis 控制根据触点组的旋转情况,设置“target ”项的rotation 所受的约束条件。
minimum 表示可接受的最小旋转角度。maximum 表示可接受的最大旋转角度。若enabled 为true,则允许旋转。activeValue 与QtQuick::PinchHandler::activeRotation 的效果相同。
当activeValue 发生变化时,会发出activeValueChanged 信号,以提供其变化的增量。此功能旨在通过多个处理程序对某个属性进行增量调整。
import QtQuick
Rectangle {
width: 100; height: 100
color: "lightsteelblue"; antialiasing: true
PinchHandler {
id: handler
target: null
xAxis.onActiveValueChanged: (delta) => parent.radius -= delta
yAxis.onActiveValueChanged: (delta) => parent.border.width += delta
rotationAxis.onActiveValueChanged: (delta) => parent.rotation += delta // add
scaleAxis.onActiveValueChanged: (delta) => parent.scale *= delta // multiply
}
WheelHandler {
acceptedModifiers: Qt.NoModifier
property: "rotation"
}
WheelHandler {
acceptedModifiers: Qt.ControlModifier
property: "scale"
}
}注意:此代码片段 是人为设计的:PinchHandler 本身已经知道如何移动、缩放和旋转其父项,但这段代码以一种非声明式的方式实现了不同的行为,旨在说明如何在特殊情况下使用activeValueChanged 。
scaleAxis group
scaleAxis.activeValue : real [read-only]
scaleAxis.enabled : bool
scaleAxis.maximum : real
scaleAxis.minimum : real
scaleAxis 根据触点之间的距离,控制设置“target ”项的scale 时的约束条件。
minimum 是可接受的最小缩放比例。maximum 是可接受的最大缩放比例。如果enabled 为true,则允许缩放。activeValue 与QtQuick::PinchHandler::activeScale 效果相同。
当activeValue 发生变化时,会发出activeValueChanged 信号,以提供增量变化的倍数。此功能旨在通过多个处理程序对某个属性进行增量调整。
import QtQuick
Rectangle {
width: 100; height: 100
color: "lightsteelblue"; antialiasing: true
PinchHandler {
id: handler
target: null
xAxis.onActiveValueChanged: (delta) => parent.radius -= delta
yAxis.onActiveValueChanged: (delta) => parent.border.width += delta
rotationAxis.onActiveValueChanged: (delta) => parent.rotation += delta // add
scaleAxis.onActiveValueChanged: (delta) => parent.scale *= delta // multiply
}
WheelHandler {
acceptedModifiers: Qt.NoModifier
property: "rotation"
}
WheelHandler {
acceptedModifiers: Qt.ControlModifier
property: "scale"
}
}注意:此代码片段 是人为设计的:PinchHandler 本身已经知道如何移动、缩放和旋转其父项,但这段代码以一种非声明式的方式实现了不同的行为,旨在说明如何在特殊情况下使用activeValueChanged 。
target : Item
该处理程序将操作的项。
默认情况下,它与parent 相同,即声明该处理程序的那个Item。不过,有时将目标设置为另一个Item会很有用,这样既可以在一个Item中处理事件,却操作另一个Item;或者将目标设置为null ,以禁用默认行为并执行其他操作。
xAxis group
xAxis 控制target 项的水平平移约束。
minimum 是平移时可接受的最小 x 坐标。maximum 是平移时可接受的最大 x 坐标。如果enabled 为真,则允许水平拖动。
当 `activeValue ` 发生变化时,会发出 `activeValueChanged ` 信号,以提供其变化的增量。此功能旨在通过多个处理程序对某个属性进行增量调整。
import QtQuick
Rectangle {
width: 100; height: 100
color: "lightsteelblue"; antialiasing: true
PinchHandler {
id: handler
target: null
xAxis.onActiveValueChanged: (delta) => parent.radius -= delta
yAxis.onActiveValueChanged: (delta) => parent.border.width += delta
rotationAxis.onActiveValueChanged: (delta) => parent.rotation += delta // add
scaleAxis.onActiveValueChanged: (delta) => parent.scale *= delta // multiply
}
WheelHandler {
acceptedModifiers: Qt.NoModifier
property: "rotation"
}
WheelHandler {
acceptedModifiers: Qt.ControlModifier
property: "scale"
}
}注意:此代码片段 是人为设计的:PinchHandler 本身已经知道如何移动、缩放和旋转其父项,但这段代码以一种非声明式的方式实现了不同的行为,旨在说明如何在特殊情况下使用activeValueChanged 。
yAxis group
yAxis 控制target 项的垂直平移约束条件。
minimum 是平移的最小允许 y 坐标。maximum 是平移的最大允许 y 坐标。如果enabled 为真,则允许垂直拖动。
当 `activeValue ` 发生变化时,会触发 `activeValueChanged ` 信号,以提供其变化量。此功能旨在通过多个处理程序对某个属性进行增量调整。
import QtQuick
Rectangle {
width: 100; height: 100
color: "lightsteelblue"; antialiasing: true
PinchHandler {
id: handler
target: null
xAxis.onActiveValueChanged: (delta) => parent.radius -= delta
yAxis.onActiveValueChanged: (delta) => parent.border.width += delta
rotationAxis.onActiveValueChanged: (delta) => parent.rotation += delta // add
scaleAxis.onActiveValueChanged: (delta) => parent.scale *= delta // multiply
}
WheelHandler {
acceptedModifiers: Qt.NoModifier
property: "rotation"
}
WheelHandler {
acceptedModifiers: Qt.ControlModifier
property: "scale"
}
}注意:此代码片段 是人为设计的:PinchHandler 本身已经知道如何移动、缩放和旋转其父项,但这段代码以一种非声明式的方式实现了不同的行为,旨在说明如何在特殊情况下使用activeValueChanged 。
Signal 文档
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 。
rotationChanged(qreal delta)
当activeRotation (以及相应的persistentRotation )发生变化时,会触发rotationChanged 信号。delta 的值表示旋转角度的累加变化量。例如,如果用户移动手指改变捏合距离,导致activeRotation 从10度变为30度,则会触发rotationChanged(20) 信号。您可以利用该信号来逐步改变项目的旋转角度:
import QtQuick
Rectangle {
width: 100; height: 100
color: "lightsteelblue"
PinchHandler {
id: handler
target: null
onRotationChanged: (delta) => parent.rotation += delta // add
onScaleChanged: (delta) => parent.scale *= delta // multiply
}
}注意:如果 直接设置persistentRotation 属性,则delta 的值为0 。
注意: 相应的处理程序 是onRotationChanged 。
scaleChanged(qreal delta)
当activeScale (以及相应的persistentScale )发生变化时,会触发scaleChanged 信号。delta 的值表示缩放比例的倍数变化。例如,如果用户移动手指改变捏合距离,使得activeScale 从2变为2.5,则会触发scaleChanged(1.25) 信号。您可以利用这一点来逐步调整项目的缩放比例:
import QtQuick
Rectangle {
width: 100; height: 100
color: "lightsteelblue"
PinchHandler {
id: handler
target: null
onRotationChanged: (delta) => parent.rotation += delta // add
onScaleChanged: (delta) => parent.scale *= delta // multiply
}
}注意:若 直接设置persistentScale 属性,则delta 的值为1 。
注意: 相应的处理程序 为 `onScaleChanged`。
translationChanged(QVector2D delta)
当activeTranslation (以及相应的persistentTranslation )发生变化时,会发出translationChanged 信号。向量delta 表示平移的变化量。您可以利用它来逐步调整项的位置:
import QtQuick
Window {
width: 320; height: 240
visible: true
title: handler.persistentRotation.toFixed(1) + "° " +
handler.persistentTranslation.x.toFixed(1) + ", " +
handler.persistentTranslation.y.toFixed(1) + " " +
(handler.persistentScale * 100).toFixed(1) + "%"
PinchHandler {
id: handler
target: null
persistentScale: 0.25
onTranslationChanged: (delta) => {
image.x -= delta.x
image.y -= delta.y
}
}
Image {
id: image
source: "images/album-cover.jpg"
scale: handler.persistentScale
x: -600; y: -450
}
}注意:若 直接设置persistentTranslation 属性,则delta 即为0, 0 。
注意: 相应的处理程序 是onTranslationChanged 。
© 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.