[QML] 交互事件深度解析:鼠标、键盘、拖拽

一 鼠标事件

核心组件MouseArea

  • 鼠标交互事件

    鼠标是 QML 中最基础的交互方式。通过 MouseArea 元素,我们可以捕获点击、悬停、按下、释放以及滚轮滚动等事件。

    核心知识点:

  • MouseArea : 必须将其 anchors.fill: parent 才能覆盖整个父组件,否则只有有内容的区域才能响应。

  • hoverEnabled: true : 这是一个关键属性。默认情况下,MouseArea 只有在鼠标按下时才会跟踪鼠标。开启此属性后,才能在鼠标仅经过(不按下)时触发 onEnteredonExited

  • onWheel : 用于处理鼠标滚轮事件,wheel.angleDelta.y 用于判断滚动方向

cpp 复制代码
import QtQuick
import QtQuick.Window

Window {
    width: 400
    height: 300
    visible: true
    title: "1. 鼠标事件演示"

    Rectangle {
        width: 200
        height: 200
        color: mouseArea.containsMouse ? "lightgreen" : "lightgray"
        text: "鼠标移入变绿,滚轮打印日志"
        anchors.centerIn: parent

        MouseArea {
            id: mouseArea
            anchors.fill: parent
            hoverEnabled: true // 关键:开启悬停支持

            // 鼠标点击
            onClicked: {
                console.log("鼠标被点击了")
            }

            // 鼠标进入区域
            onEntered: {
                console.log("鼠标进入了区域")
            }

            // 鼠标离开区域
            onExited: {
                console.log("鼠标离开了区域")
            }

            // 滚轮滚动
            onWheel: function(wheel) {
                if (wheel.angleDelta.y > 0) {
                    console.log("滚轮向上滚动")
                } else {
                    console.log("滚轮向下滚动")
                }
            }
        }
    }
}

二 键盘事件

在 QML 中,键盘事件通常绑定在具有 focus 属性的元素上(如 Rectangle, TextInput 等)。

核心知识点:

  • focus: true : 这是最容易忘记的一步。如果组件没有获取焦点,它就无法接收键盘事件。通常需要在组件加载时强制获取焦点,或者通过点击来获取焦点。
  • Keys 附加属性 : 用于定义按键处理逻辑,如 Keys.onPressed 或具体的按键 Keys.onSpacePressed
  • 事件处理 : 可以在按键事件中修改组件的属性(如坐标 x, y)。

这个示例有个很值得注意的点:

keyRect.color.toString() 为什么不直接比较,因为和有可能永远无法比较成功.

因为 QML 里的 color 属性其实是个"多面手",它的类型非常灵活,直接拿它跟字符串比,经常会因为类型不匹配或者格式不统一而踩雷。

cpp 复制代码
import QtQuick
import QtQuick.Window

Window {
    width: 400
    height: 300
    visible: true
    title: "2. 键盘事件演示"

    Rectangle {
        id: keyRect
        width: 150
        height: 150
        color: "cyan"
        anchors.centerIn: parent
        focus: true // 关键:必须设置为 true 才能接收键盘事件

        Text {
            text: "选中我,按方向键移动,按空格变色"
            anchors.centerIn: parent
            color: "black"
        }

        // 方向键移动
        Keys.onLeftPressed:  keyRect.x -= 10
        Keys.onRightPressed: keyRect.x += 10
        Keys.onUpPressed:    keyRect.y -= 10
        Keys.onDownPressed:  keyRect.y += 10

        // 空格键变色逻辑
        Keys.onSpacePressed: {
            if (keyRect.color.toString() === "#00ffff") {
                keyRect.color = "#ff00ff" // 变洋红
                console.log("颜色已切换为洋红")
            } else {
                keyRect.color = "#00ffff" // 变回青色
                console.log("颜色已切换为青色")
            }
        }
    }
}

三 拖拽事件

QML 的拖拽系统非常强大,主要依赖于 MouseAreadrag 附加属性。

核心知识点:

  • drag.target: 指定被拖拽的目标对象(通常是父组件本身)。
  • drag.axis : 限制拖拽的轴向。Drag.XAndYAxis 表示允许水平和垂直移动,也可以设置为 Drag.XAxis 仅允许水平移动。
  • Drag.active : 这是一个只读属性,表示当前是否正在进行拖拽操作。常用于与其他组件(如 DropArea)进行交互。

核心代码:Drag.active: mouseArea.drag.active

这行代码就是一个**"状态透传"** :

把鼠标区域检测到的"正在拖拽"状态,赋值给方块,让方块告诉全世界:"我正在被拖拽中,请对我做出反应!"

  • 它的作用是向外界广播:"我现在处于拖拽活跃状态"。
cpp 复制代码
import QtQuick

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

    DropArea
    {
        width: 300
        height: 300
        x:200

        Rectangle
        {
            color:"cyan"
            id:rg2
            anchors.fill: parent
        }
        onEntered:
        {
            rg2.color = "pink"
        }
        onExited:
        {
            rg2.color = "cyan"
        }
    }

    Rectangle
    {
        id:rg1
        width: 100
        height: 100
        Drag.active: mouseArea.drag.active
        MouseArea
        {
            id:mouseArea
            anchors.fill: parent
            drag.target: rg1
            drag.axis: Drag.XAndYAxis

        }
    }
}
相关推荐
ZC跨境爬虫2 小时前
海南大学交友平台开发实战 day11(实现性别图标渲染与后端数据关联+Debug复盘)
前端·python·sqlite·html·json
GISer_Jing2 小时前
前端JS面试6大核心考点详解
前端·javascript·面试
ai大模型中转api测评2 小时前
2026年前端新工具:Gemini 3.1 SVG工作流从Prompt到部署
前端·人工智能·prompt·api
yyuuuzz2 小时前
独立站搭建:从基础到避坑的实战分享
前端·javascript·github
米啦啦.2 小时前
类继承、子类拷贝构造函数、赋值运算符重载函数、多继承(虚继承)
c++·多继承·类继承·赋值运算符重载
一晌小贪欢2 小时前
PyQt5 开发一个 PDF 批量合并工具
开发语言·qt·pdf
swift192212 小时前
Qt多语言问题 —— 静态成员变量
开发语言·c++·qt
用户805533698032 小时前
现代Qt开发教程(新手篇)1.4——容器
c++·qt
星空椰2 小时前
JavaScript 基础入门:从零开始掌握变量与数据类型
开发语言·前端·javascript·ecmascript