DragHandler QML Type

拖动处理程序。更多

Import Statement: import QtQuick
Inherits:

MultiPointHandler

属性

信号

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

详细说明

DragHandler 是一个处理程序,用于以交互方式移动一个项目。与其他输入处理程序一样,默认情况下它功能齐全,可操作其target

import QtQuick

Rectangle {
    width: 100
    height: 100
    color: "lightsteelblue"
    DragHandler { }
}

它具有限制拖动范围的属性。

如果它在一个项目中声明,但被分配给不同的target ,那么它将处理parent 项目范围内的事件,但会操作target 项目:

import QtQuick

Item {
    width: 640
    height: 480

    Rectangle {
        id: feedback
        border.color: "red"
        width: Math.max(10, handler.centroid.ellipseDiameters.width)
        height: Math.max(10, handler.centroid.ellipseDiameters.height)
        radius: Math.max(width, height) / 2
        visible: handler.active
    }

    DragHandler {
        id: handler
        target: feedback
    }
}

第三种使用方法是将target 设置为null ,并以其他方式对属性变化做出反应:

import QtQuick

Item {
    width: 640
    height: 480

    DragHandler {
        id: handler
        target: null
    }

    Text {
        color: handler.active ? "darkgreen" : "black"
        text: handler.centroid.position.x.toFixed(1) + "," + handler.centroid.position.y.toFixed(1)
        x: handler.centroid.position.x - width / 2
        y: handler.centroid.position.y - height
    }
}

如果最小点数(minimumPointCount)和最大点数(maximumPointCount)设置为大于 1 的值,则用户需要向同一方向拖动这么多根手指才能开始拖动。多指拖动手势可独立于(默认)单指 DragHandler 和同一项目上的PinchHandler 进行检测,因此可用于独立于通常的捏合行为调整其他功能:例如调整倾斜变换或调整其他数值(如果target 设置为空)。但如果target 是一个项目,centroid 就是拖动的起始点,也是target 将被移动的位置(受约束)。

DragHandler 可与Drag 附加属性一起使用,以实现拖放功能。

另请参阅 Drag,MouseArea, 和Qt Quick 示例 - 指针处理程序

属性文档

acceptedButtons : flags

可激活此DragHandler 的鼠标按钮。

默认情况下,该属性设置为Qt.LeftButton 。可将其设置为鼠标按钮的 OR 组合,并忽略来自其他按钮的事件。

例如,如果一个组件(如TextEdit )已按自己的方式处理左键拖动,则可通过DragHandler 来增强该组件,在通过右键拖动时执行不同的操作:

Rectangle {
    id: canvas
    width: 640
    height: 480
    color: "#333"
    property int highestZ: 0

    Repeater {
        model: FolderListModel { nameFilters: ["*.qml"] }

        delegate: Rectangle {
            required property string fileName
            required property url fileUrl
            required property int index

            id: frame
            x: index * 30; y: index * 30
            width: 320; height: 240
            property bool dragging: ldh.active || rdh.active
            onDraggingChanged: if (dragging) z = ++canvas.highestZ
            border { width: 2; color: dragging ? "red" : "steelblue" }
            color: "beige"
            clip: true

            TextEdit {
                // drag to select text
                id: textEdit
                textDocument.source: frame.fileUrl
                x: 3; y: 3

                BoundaryRule on y {
                    id: ybr
                    minimum: textEdit.parent.height - textEdit.height; maximum: 0
                    minimumOvershoot: 200; maximumOvershoot: 200
                    overshootFilter: BoundaryRule.Peak
                }
            }

            DragHandler {
                id: rdh
                // right-drag to position the "window"
                acceptedButtons: Qt.RightButton
            }

            WheelHandler {
                target: textEdit
                property: "y"
                onActiveChanged: if (!active) ybr.returnToBounds()
            }

            Rectangle {
                anchors.right: parent.right
                width: titleText.implicitWidth + 12
                height: titleText.implicitHeight + 6
                border { width: 2; color: parent.border.color }
                bottomLeftRadius: 6
                Text {
                    id: titleText
                    color: "saddlebrown"
                    anchors.centerIn: parent
                    text: frame.fileName
                    textFormat: Text.PlainText
                }
                DragHandler {
                    id: ldh
                    // left-drag to position the "window"
                    target: frame
                }
            }
        }
    }
}

acceptedDevices : flags

可激活该DragHandler 的指向设备类型。

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

注意: 并非所有平台都能区分鼠标和触摸板;在那些能区分的平台上,你通常希望鼠标和触摸板的行为相同。


acceptedModifiers : flags

如果设置了该属性,则需要按下给定的键盘修改器才能对指针事件做出反应,否则将忽略这些事件。

例如,两个 DragHandlers 可以执行两种不同的拖放操作,具体取决于是否按下Control 修改器:

GridView {
    id: root
    width: 320
    height: 480
    cellWidth: 80
    cellHeight: 80
    interactive: false

    displaced: Transition {
        NumberAnimation {
            properties: "x,y"
            easing.type: Easing.OutQuad
        }
    }

    model: DelegateModel {
        id: visualModel
        model: 24
        property var dropTarget: undefined
        property bool copy: false
        delegate: DropArea {
            id: delegateRoot

            width: 80
            height: 80

            onEntered: drag => {
                if (visualModel.copy) {
                    if (drag.source !== icon)
                        visualModel.dropTarget = icon
                } else {
                    visualModel.items.move(drag.source.DelegateModel.itemsIndex, icon.DelegateModel.itemsIndex)
                }
            }

            Rectangle {
                id: icon
                objectName: DelegateModel.itemsIndex

                property string text
                Component.onCompleted: {
                    color = Qt.rgba(0.2 + (48 - DelegateModel.itemsIndex) * Math.random() / 48,
                                    0.3 + DelegateModel.itemsIndex * Math.random() / 48,
                                    0.4 * Math.random(),
                                    1.0)
                    text = DelegateModel.itemsIndex
                }
                border.color: visualModel.dropTarget === this ? "black" : "transparent"
                border.width: 2
                radius: 3
                width: 72
                height: 72
                anchors {
                    horizontalCenter: parent.horizontalCenter
                    verticalCenter: parent.verticalCenter
                }

                states: [
                    State {
                        when: dragHandler.active || controlDragHandler.active
                        ParentChange {
                            target: icon
                            parent: root
                        }

                        AnchorChanges {
                            target: icon
                            anchors {
                                horizontalCenter: undefined
                                verticalCenter: undefined
                            }
                        }
                    }
                ]

                Text {
                    anchors.centerIn: parent
                    color: "white"
                    font.pointSize: 14
                    text: controlDragHandler.active ? "+" : icon.text
                }

                DragHandler {
                    id: dragHandler
                    acceptedModifiers: Qt.NoModifier
                    onActiveChanged: if (!active) visualModel.dropTarget = undefined
                }

                DragHandler {
                    id: controlDragHandler
                    acceptedModifiers: Qt.ControlModifier
                    onActiveChanged: {
                        visualModel.copy = active
                        if (!active) {
                            visualModel.dropTarget.text = icon.text
                            visualModel.dropTarget.color = icon.color
                            visualModel.dropTarget = undefined
                        }
                    }
                }

                Drag.active: dragHandler.active || controlDragHandler.active
                Drag.source: icon
                Drag.hotSpot.x: 36
                Drag.hotSpot.y: 36
            }
        }
    }
}

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

如果将acceptedModifiers 设置为修改器按键的 OR 组合,则意味着必须按下所有这些修改器才能激活处理程序。

可用的修改器如下:

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

另请参阅 Qt::KeyboardModifier


acceptedPointerTypes : flags

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

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


active : bool [read-only]

只要该输入处理程序成功独占一个或多个eventPoints ,它就会保持true 。这意味着该输入处理程序会根据这些事件点的移动更新其属性,并积极操作其target (如有)。


activeTranslation : vector2d [read-only]

拖动手势时的平移。手势开始时,平移值为0, 0 ,随着事件点向下和向右拖动,平移值逐渐增大。手势结束后,平移值保持不变;当下一个拖动手势开始时,平移值再次重置为0, 0


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

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

注: 当该属性未设置或已设置为undefined 时,如果读取该值,将返回Qt.ArrowCursor

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


dragThreshold : int

用户必须拖动eventPoint 才能被视为拖动手势的距离(以像素为单位)。

默认值取决于平台和屏幕分辨率。可以通过将其设置为未定义来将其重置为默认值。拖动手势开始时的行为在不同的处理程序中有所不同。


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 ,允许大多数抓取场景,但也避免了两个 PinchHandler 争夺同一接触点的情况。


margin : real

parent 项目边界外的余量,在此范围内eventPoint 可以激活此处理程序。例如,您可以允许用户从附近的位置拖动小物件,从而使拖动变得更容易:

Rectangle {
    width: 24
    height: 24
    border.color: "steelblue"
    Text {
        text: "it's\ntiny"
        font.pixelSize: 7
        rotation: -45
        anchors.centerIn: parent
    }

    DragHandler {
        margin: 12
    }
}

parent : Item

处理程序作用域的Item ;声明处理程序的项目。处理程序将代表该 Item 处理事件,这意味着如果指针事件中至少有一个eventPoints 出现在 Item 的内部,那么该指针事件就是相关的。最初target() 是相同的,但可以重新分配。

另请参阅 targetQObject::parent()。


persistentTranslation : vector2d

如果目标语不是null ,则将应用于目标语的翻译。否则,可以使用绑定对该值进行任意操作。在执行拖动手势时,activeTranslation ;手势结束后,该值保持不变。


snapMode : enumeration

该属性包含抓取模式。

捕捉模式用于将目标项的中心点捕捉到eventPoint

可能的值:

常量说明
DragHandler.NoSnap从不抓取
DragHandler.SnapAuto如果eventPoint目标项之外按下,且 目标parent 项的后代,则目标会捕捉(默认值)
DragHandler.SnapWhenPressedOutsideTarget如果eventPoint目标之外按下,则目标会咬合
DragHandler.SnapAlways始终抓取

target : Item

此处理程序将处理的项目。

默认情况下,它与parent 相同,即处理程序所声明的项。不过,有时也可以将目标设置为不同的项目,以便处理一个项目中的事件,但操作另一个项目;或者将目标设置为null ,禁用默认行为,而执行其他操作。


xAxis group

xAxis.activeValue : real [read-only]

xAxis.enabled : bool

xAxis.maximum : real

xAxis.minimum : real

xAxis 控制水平拖动的约束条件。

minimum 是 的最小可接受值,应用于 。 是 的最大可接受值,应用于 。如果 为 true,则允许水平拖动。 与 相同。x target maximum x target enabled activeValue activeTranslation.x

activeValueChanged 信号会在activeValue 发生变化时发出,以提供变化的增量。这是为了通过多个处理程序增量调整一个属性。


yAxis group

yAxis.activeValue : real [read-only]

yAxis.enabled : bool

yAxis.maximum : real

yAxis.minimum : real

yAxis 控制垂直拖动的约束条件。

minimum 是 的最小可接受值,应用于 。 是 的最大可接受值,应用于 。如果 为 true,则允许垂直拖动。 与 相同。y target maximum y target enabled activeValue activeTranslation.y

activeValueChanged 信号会在activeValue 发生变化时发出,以提供变化的增量。该信号用于通过多个处理程序增量调整一个属性:

import QtQuick

Rectangle {
    width: 50; height: 200

    Rectangle {
        id: knob
        width: parent.width; height: width; radius: width / 2
        anchors.centerIn: parent
        color: "lightsteelblue"

        Rectangle {
            antialiasing: true
            width: 4; height: 20
            x: parent.width / 2 - 2
        }

        WheelHandler {
            property: "rotation"
        }
    }

    DragHandler {
        target: null
        dragThreshold: 0
        yAxis.onActiveValueChanged: (delta)=> { knob.rotation -= delta }
    }
}

信号文档

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


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