目录
- 引言
- 核心代码
- 完整代码
引言
因为项目需要需要进行组件移动、缩放的开发,具体要求如下:
- 鼠标滚轮,实现垂直移动
- Ctrl+鼠标滚轮,实现缩放
- Alt+鼠标滚轮,实现水平移动
- 触控板移动,实现垂直、水平移动
- 触控板双指,实现缩放

核心代码
实现上述功能主要使用到两个组件MouseArea、PinchArea,MouseArea主要是进行鼠标事件的操作和部分触控板事件的操作,PinchArea主要是Mac下识别触控板的双指缩放。需要注意的是鼠标滚轮垂直移动和触控板垂直移动手势是混合在一起的,可以通过wheel.angleDelta.y是否为120的倍数去判断,如下所示:
	if (wheel.angleDelta.y && !(wheel.angleDelta.y % 120)) {
		// ...
	}
	else {
		// ...
	}
上述功能中需要识别Ctrl、Alt按键是否按下,需要通过wheel事件的modifiers 属性进行判断,如下所示:
MouseArea {
	onWheel: {
		if (wheel.modifiers & Qt.AltModifier) {
    		//..
		}
		else if (wheel.modifiers & Qt.ControlModifier) {
     		//..               
		}
		else {
			//..
		}
	}
}
完整代码
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
    id: root
    width: 640
    height: 480
    visible: true
    //title: qsTr("Hello World")
    Rectangle {
        id: rect
        width: 100
        height: 100
        x: (parent.width - width) / 2
        y: (parent.height - height) / 2
        color: "blue"
    }
    MouseArea {
        id: mouseArea
        anchors.fill: parent
    }
    PinchArea {
        // Mac手势使用
        id: pinchArea
        anchors.fill: parent
        pinch.maximumScale: 20
        pinch.minimumScale: 0.2
    }
    Connections {
        target: mouseArea
        function onWheel(wheel) {
            if (wheel.pixelDelta === Qt.point(0, 0)
                    && wheel.angleDelta === Qt.point(0, 0)) {
                return
            }
            //console.log("wheel.angleDelta", wheel.angleDelta)
            //console.log("wheel.pixelDelta", wheel.pixelDelta)
            if (Qt.platform.os == "windows") {
                // Windows处理
                if (wheel.modifiers & Qt.AltModifier) {
                    // 左右滚动
                    if (wheel.angleDelta.x > 0) {
                        // 往左滚动
                        rect.x = Math.max(rect.x - 50, 0)
                    }
                    else {
                        // 往右滚动
                        rect.x = Math.min(rect.x + 50, root.width - rect.width)
                    }
                }
                else if (wheel.modifiers & Qt.ControlModifier) {
                    // 缩放
                    if (wheel.angleDelta.y > 0) {
                        rect.scale = Math.min(rect.scale + 0.1, 2)
                    }
                    else {
                        rect.scale = Math.max(rect.scale - 0.1, 1)
                    }
                }
                else {
                    if (wheel.angleDelta.y && !(wheel.angleDelta.y % 120)) {
                        // 鼠标滚动
                        if (wheel.angleDelta.y > 0) {
                            // 向上滚动
                            rect.y = Math.max(rect.y - 50, 0)
                        }
                        else {
                            // 向下滚动
                            rect.y = Math.min(rect.y + 50, root.height - rect.height)
                        }
                    }
                    else {
                        // 触摸板滚动
                        let tempX = rect.x - wheel.angleDelta.x
                        tempX = Math.max(tempX, 0)
                        tempX = Math.min(tempX, root.width - rect.width)
                        rect.x = tempX
                        let tempY = rect.y + wheel.angleDelta.y
                        tempY = Math.max(tempY, 0)
                        tempY = Math.min(tempY, root.height - rect.height)
                        rect.y = tempY
                    }
                }
            }
            else {
                // Mac处理
                if (wheel.modifiers & Qt.AltModifier) {
                    // 左右滚动
                    if (wheel.angleDelta.y > 0) {
                        // 往左滚动
                        rect.x = Math.max(rect.x - 50, 0)
                    }
                    else {
                        // 往右滚动
                        rect.x = Math.min(rect.x + 50, root.width - rect.width)
                    }
                }
                else if (wheel.modifiers & Qt.ControlModifier) {
                    // 缩放
                    if (wheel.angleDelta.y > 0) {
                        rect.scale = Math.min(rect.scale + 0.1, 2)
                    }
                    else {
                        rect.scale = Math.max(rect.scale - 0.1, 1)
                    }
                }
                else {
                    if (wheel.angleDelta.y && !(wheel.angleDelta.y % 120)) {
                        // 鼠标滚动
                        if (wheel.angleDelta.y > 0) {
                            // 向上滚动
                            rect.y = Math.max(rect.y - 50, 0)
                        }
                        else {
                            // 向下滚动
                            rect.y = Math.min(rect.y + 50, root.height - rect.height)
                        }
                    }
                    else {
                        // 触摸板滚动
                        let tempX = rect.x + wheel.pixelDelta.x
                        tempX = Math.max(tempX, 0)
                        tempX = Math.min(tempX, root.width - rect.width)
                        rect.x = tempX
                        let tempY = rect.y + wheel.pixelDelta.y
                        tempY = Math.max(tempY, 0)
                        tempY = Math.min(tempY, root.height - rect.height)
                        rect.y = tempY
                    }
                }
            }
        }
    }
    Connections {
        target: pinchArea
        property double oriScale: 1
        function onPinchStarted(pinch) {
            oriScale = rect.scale
        }
        function onPinchUpdated(pinch) {
            let tempScale = pinch.scale * oriScale
            tempScale = Math.min(tempScale, 2)
            tempScale = Math.max(tempScale, 1)
            rect.scale = tempScale
        }
        //function onPinchFinished(pinch) {
        //    rect.scale = pinch.scale * oriScale
        //    console.log("onPinchFinished", pinch.scale)
        //}
    }
}


















