QML学习笔记(二十四)QML的MouseArea的drag

前言

从本节开始,我们重新学习一下鼠标和键盘的应用。
其实在之前学习信号处理器的时候,就已经深入学习MouseArea鼠标相关的各种槽函数,并基于这些信号处理和一些临时变量,我们实现了矩形的拖拽。
以下是跳转链接:QML学习笔记(十五)QML的信号处理器(MouseArea)
代码量不多,这里顺便贴一下:

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("DragRect")

    Rectangle {
        id: rectId
        width: 150; height: 150; color: "red"

        MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton
            hoverEnabled: true

            property bool pressed: false
            property real startSceneX: 0   // 按下时全局坐标
            property real startSceneY: 0
            property real startRectX: 0    // 按下时矩形左上角
            property real startRectY: 0

            onPressed: {
                pressed = true
                var scenePos = mapToItem(null, mouse.x, mouse.y)   // 映射到窗口坐标
                startSceneX = scenePos.x
                startSceneY = scenePos.y
                startRectX  = rectId.x
                startRectY  = rectId.y
            }

            onPositionChanged: {
                if (pressed) {
                    var curScene = mapToItem(null, mouse.x, mouse.y)
                    rectId.x = startRectX + (curScene.x - startSceneX)
                    rectId.y = startRectY + (curScene.y - startSceneY)
                }
            }

            onReleased: pressed = false
        }
    }
}

然而今天我们再重温一下MouseArea,并学习如何通过其drag方法来实现组件的拖拽,这将更加高效。

一、MouseAre和drag

先看以下帮助文档:
在这里插入图片描述

测试代码如下:

    Rectangle{
        id: dragContainerId
        width:parent.width
        height:200
        color: "beige"
        y: 250

        Rectangle{
            id: draggableRectId
            width: 50
            height: width
            color: "blue"
        }
        
        MouseArea{
            anchors.fill: parent
            drag.target: draggableRectId
//            drag.axis: Drag.XAxis
            drag.axis: Drag.XAndYAxis
            drag.minimumX: 0
            drag.maximumX: dragContainerId.width - draggableRectId.width
        }
    }

运行效果:
请添加图片描述
可以看到,这段代码非常简洁,甚至没有重载任何的槽函数。

		MouseArea{
            anchors.fill: parent
            drag.target: draggableRectId
//            drag.axis: Drag.XAxis
            drag.axis: Drag.XAndYAxis
            drag.minimumX: 0
            drag.maximumX: dragContainerId.width - draggableRectId.width
        }

在这段代码中,我们给MouseArea的drag属性设置了对象target,此后这个target的移动代码便不需要我们手动处理了。我们仅仅需要设置最小最大的x和y范围即可()不出界。
它甚至还提供了axis这种属性,如果设置成drag.axis: Drag.XAxis ,则告诉 MouseArea 的拖拽功能,只能沿水平方向(X 轴)拖动,垂直方向被锁定,Y 坐标保持不变。
它的取值枚举:
Drag.XAxis → 水平拖拽
Drag.YAxis → 垂直拖拽
Drag.XAndYAxis → 双向自由拖拽(默认)
直观上看drag.axis: Drag.XAxis,就感觉y轴被锁了,怎么拖拽都只会让target在x轴上移动,这在某些情形下会有用。

二、对比两种方法

由于drag方法比较简单,且不需要自己计算,我就不多解释了。这里将之前的方法拿过来,和drag对比一下:
以下是kimi的总结:
两段代码都能“拖”,但底层思路完全不同:

  1. 手动坐标法(红矩形)

    • 不用 drag.* 任何属性
    • 完全靠 onPressed / onPositionChanged 自己算坐标 → 直接改 x/y
    • 自由度最高:可同时拖 X+Y、加惯性、旋转、缩放
    • 代码量稍大,边界/轴约束都要自己写
  2. 内置 drag 导轨法(蓝矩形)

    • 一句 drag.target 告诉 MouseArea“替我拖”
    • drag.axis / min / max 让 Qt 帮你做导轨+限位
    • 引擎层替你改 x
    • 只能做平移;想同时拖 Y 就把 drag.axis 换成 XAndYAxis 或再加 drag.minimumY / maximumY
    • 代码极简,适合“纯平移+硬边界”场景

一句话总结:
“前者是‘自己拉车’,后者是‘Qt 给你铺轨道并推车’;要特效用手动,要快出平移用 drag。”

三、总结:

如果只是想实现简单拖拽的话,用drag方法是明智的选择。
但不要忘了,这种方法适用于在一个大的MouseArea范围中,拖拽一个指定的target。但很多时候,我们希望点击了矩形再实现拖拽,甚至希望短暂长按矩形后,再进行拖拽。这种情形的话更适合用鼠标三态的信号处理来自行实现,一般我们只需要在自行简单计算坐标,也不是什么很难的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值