新闻详情

新闻详情

首页 / 资讯中心 / 详情

QML 拖拽篇:自由移动与单轴约束

发布时间:2026/9/2 21:39:11来源:尧图网络
QML 拖拽篇:自由移动与单轴约束
目录基础自由拖拽演示代码关键逻辑解析单轴约束拖拽演示代码关键逻辑解析运行验证小结系列文章我们常常会有这样的需求把窗口拖到屏幕边缘、拖动滑块的圆钮、把任务挪到另一个列表。QML 里实现拖拽的基础就是MouseArea上那几个drag.*属性——指定拖谁、往哪个方向拖、最多拖多远。下面从最简单的自由拖拽开始再讲怎么把拖拽限制在单一方向上。基础自由拖拽一个蓝色方块放在网格画布中间按住拖动可以满画布跑但永远出不了画布边界。松开时底部显示方块当前坐标旁边有个重置位置按钮把它拉回中心。演示代码import QtQuick import QtQuick.Controls import QtQuick.Layouts FadeInAnimation { ColumnLayout { anchors.fill: parent anchors.margins: 20 spacing: 15 // ... 省略标题组件 TitleSeparator ... // 拖拽画布 Rectangle { id: canvas Layout.alignment: Qt.AlignHCenter width: 540 height: 300 radius: 10 color: #FAFAFA border.color: #ddd border.width: 1 clip: true // 网格背景便于观察位置 Canvas { anchors.fill: parent onPaint: { var ctx getContext(2d) ctx.strokeStyle #EEEEEE ctx.lineWidth 1 for (var x 0; x width; x 30) { ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, height); ctx.stroke() } for (var y 0; y height; y 30) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(width, y); ctx.stroke() } } } // 可拖拽方块 Rectangle { id: dragBox width: 90 height: 90 radius: 12 color: dragArea.pressed ? #0E7BD9 : #1296FF x: canvas.width / 2 - 45 y: canvas.height / 2 - 45 Behavior on color { ColorAnimation { duration: 120 } } Text { anchors.centerIn: parent text: 拖我 color: white font.bold: true font.pointSize: 14 } Drag.active: dragArea.drag.active Drag.dragType: Drag.None MouseArea { id: dragArea anchors.fill: parent drag.target: dragBox drag.axis: Drag.XAndYAxis drag.minimumX: 0 drag.maximumX: canvas.width - dragBox.width drag.minimumY: 0 drag.maximumY: canvas.height - dragBox.height cursorShape: Qt.SizeAllCursor onPositionChanged: statusText.text 拖拽中… onReleased: { statusText.text 已释放 位置: ( Math.round(dragBox.x) , Math.round(dragBox.y) ) } } } // 状态提示 Text { id: statusText anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.bottomMargin: 10 text: 拖拽方块自由移动 font.pointSize: 12 color: #999 } } RowLayout { Layout.alignment: Qt.AlignHCenter spacing: 20 Text { text: 当前坐标: ( Math.round(dragBox.x) , Math.round(dragBox.y) ) font.pointSize: 13 color: #1296FF font.bold: true } Button { text: 重置位置 onClicked: { dragBox.x canvas.width / 2 - 45 dragBox.y canvas.height / 2 - 45 statusText.text 拖拽方块自由移动 } } } Text { Layout.alignment: Qt.AlignHCenter Layout.preferredWidth: 540 text: drag.axis: Drag.XAndYAxis → 仅可在画布范围内移动minimumX/Y ~ maximumX/Y font.pointSize: 10 color: #999 horizontalAlignment: Text.AlignHCenter wrapMode: Text.Wrap } Item { Layout.fillHeight: true } } }关键逻辑解析四件套target、axis、minimum、maximum实现拖拽靠 MouseArea 上的一组drag属性drag.target指定被拖动的对象这里是方块 dragBox。它填满了 MouseArea所以鼠标按住方块就能拖drag.axis决定拖拽方向Drag.XAndYAxis表示水平和垂直都能动drag.minimumX/drag.maximumX限定水平范围minimumY/maximumY限定垂直范围。上界写canvas.width - dragBox.width是因为方块有 90 宽坐标超过这个值右侧就出界了这套约束配齐后方块天然出不了画布不需要自己写撞墙判断。按下变深色给个反馈color: dragArea.pressed ? #0E7BD9 : #1296FF让方块在按住时变成深蓝色配一个Behavior on color做 120 毫秒的颜色过渡。加上cursorShape: Qt.SizeAllCursor鼠标悬停变成四向箭头用户一眼就知道这个能拖。监听状态汇报坐标onPositionChanged在拖拽过程中触发把状态文字改成拖拽中…onReleased在松开时把方块当前坐标写到底部。坐标用Math.round(dragBox.x)取整读起来干净。这里用的是纯物理移动不牵扯 Drag 会话所以Drag.dragType: Drag.None关掉系统拖拽避免产生多余的拖拽预览。单轴约束拖拽一个横的、一个竖的两条轨道各放一个圆形滑块。横的只能左右滑竖的只能上下滑滑块永远沿着轨道中线走旁边实时显示滑到哪了。这正是滑杆类控件最常见的实现思路。演示代码import QtQuick import QtQuick.Layouts FadeInAnimation { ColumnLayout { anchors.fill: parent anchors.margins: 20 spacing: 18 // ... 省略标题组件 TitleSeparator ... // 水平拖拽轨道 Rectangle { id: hTrack Layout.alignment: Qt.AlignHCenter width: 480 height: 70 radius: 8 color: #FAFAFA border.color: #ddd border.width: 1 // 轨道中线 Rectangle { anchors.verticalCenter: parent.verticalCenter x: 12 width: parent.width - 24 height: 2 color: #E0E0E0 } Text { x: 12 y: 8 text: XAxis仅水平拖拽 font.pointSize: 10 color: #999 } Rectangle { id: hKnob width: 50 height: 50 radius: 25 color: hMouse.pressed ? #0E7BD9 : #1296FF y: (hTrack.height - height) / 2 x: 12 Behavior on color { ColorAnimation { duration: 120 } } Text { anchors.centerIn: parent text: ↔ color: white font.pointSize: 20 font.bold: true } MouseArea { id: hMouse anchors.fill: parent drag.target: hKnob drag.axis: Drag.XAxis drag.minimumX: 12 drag.maximumX: hTrack.width - hKnob.width - 12 cursorShape: Qt.SizeHorCursor } } Text { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.bottomMargin: 4 text: x Math.round(hKnob.x) font.pointSize: 11 color: #1296FF } } // ... 省略垂直轨道 vTrack与水平轨道对称仅 axis 改为 Drag.YAxis、cursorShape 改为 Qt.SizeVerCursor... Item { Layout.fillHeight: true } } }关键逻辑解析drag.axis 决定自由度水平滑块写drag.axis: Drag.XAxis于是 x 可以变、y 被锁死——滑块被约束在中线上不会乱跑。垂直滑块反过来写Drag.YAxis。改一个属性值拖拽的自由度就从二维变成一维。轴方向与光标匹配水平拖拽配cursorShape: Qt.SizeHorCursor左右箭头垂直配Qt.SizeVerCursor上下箭头滑块上的 “↔” 和 “↕” 文字进一步提示方向。最小/最大值的边界计算水平滑块minimumX: 12、maximumX: hTrack.width - hKnob.width - 12两边各留 12 像素边距。滑块中心对齐轨道中线的关键是y: (hTrack.height - height) / 2——把滑块垂直居中水平拖拽就永远贴着中线走。drag.axis 有四种取值Drag.XAxis仅水平音量条、进度条Drag.YAxis仅垂直滚动条、高度调节Drag.XAndYAxis双轴自由自由摆放的元素Drag.None禁用拖拽临时锁住某元素。运行验证Qt Creator 打开示例的 CMakeLists.txt按 CtrlR 运行自由拖拽按住蓝色方块满画布拖动观察坐标变化点重置位置看方块回中心单轴约束拖横滑块只能左右动拖竖滑块只能上下动观察 x / y 数值变化。小结拖动窗口标题栏移动整个窗口把drag.target指向窗口根元素即可。单轴滑块可以扩展成音量条用Math.round(hKnob.x)换算成 0-100 的值。双轴拖拽加一条Behavior on x动画可以让元素松手后弹回某个区域做卡片归位效果。用drag.filterChildren可以让父级 MouseArea 同时处理多个子元素。系列文章QML 拖拽篇自由移动与单轴约束本篇QML 拖拽篇接收拖拽与数据交换QML 拖拽篇拖拽吸附与列表排序QML 拖拽篇跨列拖拽与数字拼图已验证环境Qt 版本Qt 6.11.1操作系统Windows 11项目地址QML 示例合集V2.0 - qml_drag_drop
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

考研资料网站的信任基建与工程实践 2026/9/2 22:30:22

考研资料网站的信任基建与工程实践

简介:这是一套面向计算机专业本科生的毕业设计级Web应用资源,聚焦教育/考试场景下的考研资料共享需求,解决学习资源分散、获取门槛高、协作效率低等实际问题,适用于毕业设计、课程设计、大创项目及全栈开发练手。压缩包共121个文件…

阅读更多 →
如何快速上手 oh-my-codex:给 Codex CLI 配上工作流、钩子和团队的完整指南 2026/9/2 22:30:22

如何快速上手 oh-my-codex:给 Codex CLI 配上工作流、钩子和团队的完整指南

如何快速上手 oh-my-codex:给 Codex CLI 配上工作流、钩子和团队的完整指南 【免费下载链接】oh-my-codex OmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more. 项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex …

阅读更多 →
嵌入式开发必知:STM32启动流程与中断向量表深度剖析 2026/9/2 22:30:22

嵌入式开发必知:STM32启动流程与中断向量表深度剖析

嵌入式开发里有一个很常见的现象:程序烧进去之后,板子不按预期跑,甚至一上电就死机。很多人习惯性地打开 main 函数从头查,查了好几遍逻辑都没问题,最后才发现问题根本不在 main 里,而在 main 跑起来之前的…

阅读更多 →
STM32启动流程详解:从复位到main的完整链路与Bootloader跳转实践 2026/9/2 22:30:22

STM32启动流程详解:从复位到main的完整链路与Bootloader跳转实践

当你拿到一块 STM32 板子,烧完程序,上电后发现预期中的现象没有出现,第一反应往往是检查电路、确认引脚、怀疑传感器。但有一类问题,它的根因既不在外设配置,也不在硬件连接,而是发生在 main 函数执行之前的…

阅读更多 →
OracleXE112_Win64压缩包安装配置与排错实战指南 2026/9/2 22:30:22

OracleXE112_Win64压缩包安装配置与排错实战指南

简介:这是一份 Oracle Database 11g Express Edition(XE)的 Windows x64 安装资源包,面向需要在本地搭建轻量级数据库环境的学习者、开发者与运维初学者。XE 版本免费、部署简单且占资源较少,适合入门练习、开发测试或…

阅读更多 →
PHP泛域名站群系统开发实战:从DNS解析到Nginx配置与性能优化 2026/9/2 22:27:21

PHP泛域名站群系统开发实战:从DNS解析到Nginx配置与性能优化

简介:这套PHP泛域名站群源码面向需要批量创建子站点、统一管理多域名内容的开发者或SEO运营者,基于单一代码库配合泛解析与URL重写,为每个子域名自动路由页面。包内共18个文件,以PHP逻辑、HTML模板、TXT说明为主,辅以C…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞