QML如何围绕鼠标点对已旋转的Item实现正确缩放
问题原因
- Qt Quick的
transform变换按列表顺序从后向前执行,你当前代码中先声明Scale、后声明Rotation,实际渲染时会先应用旋转、再应用缩放,两套变换的参考坐标系不统一。 - 原有位置补偿逻辑仅适配了无旋转的场景,没有考虑旋转带来的坐标系偏转,直接沿x/y轴加偏移量的计算方式在旋转后完全不匹配实际坐标偏移方向,必然出现位置跳变。
- 原有代码存在属性引用错误:
maxZoom/minZoom是定义在sample矩形上的属性,calculateZoom函数中错误引用了mouseArea下的同名属性,会触发属性不存在的运行警告。
修复方案
不用手动计算旋转对应的三角函数偏移,直接用Qt Quick内置的坐标映射APImapToItem做位置补偿,这套逻辑会自动把旋转、缩放等所有变换的影响计算在内,不需要针对旋转单独调整公式,鲁棒性更强:
- 缩放前先记录鼠标点击位置在父坐标系下的坐标,这个点在缩放全程要保持固定
- 更新缩放比例和缩放原点
- 计算缩放后同一点在父坐标系下的新位置,将前后位置的差值补到矩形的x/y坐标上,保证鼠标点位置不发生跳变
修复后的完整代码如下:
import QtQuick 2.0 Rectangle { id: root color: "gray" width: 1200 height: 800 Rectangle { color: "black" width: 360 height: 200 opacity: 0.5 x: 500 y: 350 } Rectangle { id: sample color: "green" width: 360 height: 200 opacity: 0.5 x: 500 y: 350 property real currZoom: 1 property real maxZoom: 5 property real minZoom: 0.5 transform: [ Scale { id: scaler xScale: sample.currZoom yScale: sample.currZoom }, Rotation{ id: rotation origin.x: 180 origin.y: 100 angle: 30 } ] MouseArea{ id: mouseArea anchors.fill: parent drag.target: sample onClicked: mouse => { zoom(true, mouse.x, mouse.y) } onWheel: (wheel) => { var isIn = wheel.angleDelta.y > 0 zoom(isIn, wheel.x, wheel.y) wheel.accepted = true } function zoom(isIn, x, y) { // 记录缩放前鼠标点在父坐标系下的位置,该点需保持固定 const fixedPos = sample.mapToItem(root, x, y) // 更新缩放参数 const oldZoom = sample.currZoom sample.currZoom = calculateZoom(isIn, oldZoom) scaler.origin.x = x scaler.origin.y = y // 计算缩放后的位置偏差并补偿 const newPos = sample.mapToItem(root, x, y) sample.x += fixedPos.x - newPos.x sample.y += fixedPos.y - newPos.y } function calculateZoom(isIn, prevZoom) { var newZoom = isIn ? prevZoom + 0.1 : prevZoom - 0.1 // 修正属性引用路径 if (newZoom > sample.maxZoom) newZoom = sample.maxZoom if (newZoom < sample.minZoom) newZoom = sample.minZoom return newZoom } } } }
补充说明
- 这套实现不需要手动维护冗余的
currX/currY属性存储缩放原点,直接给scaler的origin赋值即可。 - 滚轮事件加了
wheel.accepted = true避免事件冒泡导致的异常缩放行为。 - 不管后续调整旋转角度、修改变换顺序,这套缩放逻辑都可以正常工作,不需要额外调整坐标计算逻辑。
内容的提问来源于stack exchange,提问作者Alexander Satsukevich
相关产品推荐
相关产品推荐

