史上最强的 QML 思维导图

这是一份详尽的QML学习资源,涵盖QML核心概念、基础元素、模型视图、画布与绘图、数据存储、网络编程及Web开发。包括QML布局、颜色表示、事件处理、Canvas绘制、网络请求等内容,配合实例源码,适合快速学习和记忆。

作者: 一去、二三里
QQ 技术交流群: 242790253
个人微信: iwaleon(加我微信,邀请入 500 人微信群)
微信公众号: 高效程序员

这是一份史上最强、最高清、最好用的 QML 思维导图,所有内容均来自专栏 《细说 QML》

  • 全新的 QML
  • 基于 Qt6 + CMake
  • 清晰的思维导图(帮助快速记忆,更加易于学习)
  • 透彻的示例程序(图文并茂,每篇文章都有完整的示例源码,且解释详细)
  • 超全面的章节(涉及语法、常见元素、模型视图、画布与绘图、动画效果、粒子系统、着色器、多媒体、JavaScript、C++ 交互等)

QML 核心

  1. QML 中的 5 大布局
    在这里插入图片描述

  2. QML 颜色表示法
    在这里插入图片描述

  3. QML 鼠标事件
    在这里插入图片描述

  4. QML 键盘事件
    在这里插入图片描述

  5. QML 定时器
    在这里插入图片描述

  6. QML 中的 z-order
    在这里插入图片描述

  7. QML 可重用组件
    在这里插入图片描述

  8. QML 单例组件
    在这里插入图片描述

  9. QML 国际化
    在这里插入图片描述

基础元素

  1. QML Rectangle 元素
    在这里插入图片描述

  2. QML Text 元素
    在这里插入图片描述

  3. QML Image 元素
    在这里插入图片描述

动画效果

  1. QML 状态、过渡和动画

在这里插入图片描述

  1. QML 状态

在这里插入图片描述

  1. QML 动画框架

在这里插入图片描述
4. QML 基本动画

在这里插入图片描述

模型视图

  1. QML 模型视图
    在这里插入图片描述

  2. QML Repeater 重复器
    在这里插入图片描述

  3. QML ListView 列表视图
    在这里插入图片描述

  4. QML Path 路径

在这里插入图片描述

  1. QML PathView 路径视图

在这里插入图片描述

画布与绘图

  1. QML Canvas 绘制基础形状
    在这里插入图片描述

  2. QML Canvas 绘制图像
    在这里插入图片描述

  3. QML Canvas 绘制文本
    在这里插入图片描述

  4. QML Canvas 渐变和阴影
    在这里插入图片描述

  5. QML Canvas 像素处理
    在这里插入图片描述

  6. QML Canvas 裁剪
    在这里插入图片描述

  7. QML Canvas 保存画布内容
    在这里插入图片描述

  8. QML Canvas 几何变换(平移/旋转/缩放)
    在这里插入图片描述

  9. QML Canvas 制作动画
    在这里插入图片描述

数据存储

  1. QML 保存用户配置
    在这里插入图片描述

  2. QML 数据库存储
    在这里插入图片描述

网络编程

  1. QML HTTP 请求
    在这里插入图片描述

  2. QML WebSocket 客户端
    在这里插入图片描述

  3. QML WebSocket 服务器
    在这里插入图片描述

Web 开发

  1. QML 创建 Web 混合应用
    在这里插入图片描述

  2. QML WebEngineView 调用 JavaScript

在这里插入图片描述

  1. 利用 WebChannel 实现 QML 和 Web 双向通信

在这里插入图片描述

  1. QML WebEngineView 全屏和退出

在这里插入图片描述

更多干货分享,请关注我的微信公众号【高效程序员】,有趣、好玩、靠谱!

<think>我们使用QtQuick来绘制思维导图曲线。在QML中,我们可以使用Canvas元素进行自定义绘图,也可以使用QtQuick图形项(如PathView、Shape等)来绘制曲线。这里我们选择使用Canvas来绘制,因为它提供更底层的控制,适合绘制自定义曲线(比如贝塞尔曲线)。思路:1.定义节点:每个节点包括位置和文本。节点可以用矩形或圆形表示。2.定义连接:连接两个节点,用曲线(贝塞尔曲线)连接。3.在Canvas中绘制连接线和节点。我们将创建一个MindMap组件,包含一个Canvas,然后使用JavaScript在Canvas上绘制。由于您使用的是Qt5.14,因此我们将使用Qt5.14对应的QML语法。注意:我们使用二次贝塞尔曲线(quadraticCurveTo)来绘制平滑的曲线。步骤:1.定义Canvas,并设置合适的宽高。2.用JavaScript函数在Canvas上绘制:a.遍历所有的连接,绘制曲线(从父节点到子节点,中间设置一个控制点来控制曲线弯曲度)。b.绘制节点(圆形或矩形)和文本。示例代码:首先,我们定义一个节点对象,这里我们可以使用QtObject,但是QML中我们通常直接使用属性。参考引用[1]中,QtObject的用法,我们可以定义自己的数据类型,但这里为了简单,我们直接使用JavaScript对象。下面是一个简单的QML文件示例:</think> 以下是一个基于 Qt5.14 和 QML思维导图曲线实现示例,包含详细注释说明。该实现使用 Canvas 元素绘制贝塞尔曲线连接节点,支持动态布局和节点交互。 ```qml import QtQuick 2.14 import QtQuick.Window 2.14 Window { width: 800 height: 600 visible: true title: "Qt QML 思维导图" // 思维导图控制器(负责逻辑处理) MindMapController { id: controller } // 主画布容器 Item { id: mindMapCanvas anchors.fill: parent // 背景区域 Rectangle { anchors.fill: parent color: "#f8f9fa" border.color: "#dee2e6" } // 使用Canvas绘制连接线 Canvas { id: connectionCanvas anchors.fill: parent renderTarget: Canvas.Image // 使用图像渲染提高性能 // 当需要重绘时触发 onPaint: { var ctx = getContext("2d"); ctx.clearRect(0, 0, width, height); // 清除画布 // 绘制所有连接 for (var i = 0; i < controller.connections.length; i++) { var conn = controller.connections[i]; var fromNode = controller.getNodeById(conn.fromId); var toNode = controller.getNodeById(conn.toId); if (fromNode && toNode) { // 设置曲线样式 ctx.strokeStyle = "#3498db"; // 线条颜色 ctx.lineWidth = 2; // 线条宽度 ctx.lineCap = "round"; // 线条端点样式 ctx.beginPath(); // 起点:父节点位置 ctx.moveTo(fromNode.x + fromNode.width/2, fromNode.y + fromNode.height/2); // 计算控制点(实现平滑曲线效果) var controlX = (fromNode.x + toNode.x) / 2; var controlY = (fromNode.y + toNode.y) / 2 - 50; // 绘制二次贝塞尔曲线 // quadraticCurveTo(cp1x, cp1y, x, y) ctx.quadraticCurveTo(controlX, controlY, toNode.x + toNode.width/2, toNode.y + toNode.height/2); ctx.stroke(); // 执行绘制 } } } } // 思维导图节点(动态创建) Repeater { model: controller.nodes // 单个节点组件 Rectangle { id: node x: modelData.x y: modelData.y width: 120 height: 60 radius: 8 color: mouseArea.containsPress ? "#d1e7dd" : "#e2f0f9" // 点击反馈 border.color: "#3498db" border.width: 2 // 节点文本 Text { anchors.centerIn: parent text: modelData.text font.pixelSize: 14 elide: Text.ElideRight } // 交互处理 MouseArea { id: mouseArea anchors.fill: parent drag.target: node acceptedButtons: Qt.LeftButton | Qt.RightButton // 节点拖动处理 onPositionChanged: { if (drag.active) { controller.updateNodePosition(modelData.id, node.x, node.y); connectionCanvas.requestPaint(); // 更新连接线 } } // 右键添加子节点 onClicked: (mouse) => { if (mouse.button === Qt.RightButton) { controller.addChildNode(modelData.id, "新节点"); } } } } } // 添加根节点按钮 Rectangle { x: 20 y: 20 width: 100 height: 40 color: "#4caf50" radius: 4 Text { anchors.centerIn: parent text: "添加根节点" color: "white" } MouseArea { anchors.fill: parent onClicked: controller.addRootNode("中心主题") } } } // 思维导图控制器(JS实现) QtObject { id: controller // 节点数据模型 property list<Node> nodes: [ Node { id: "root"; x: 400; y: 300; text: "中心主题" } ] // 连接关系:[fromId, toId] property list<Connection> connections: [] // 添加根节点 function addRootNode(text) { var newNode = Qt.createQmlObject( `import QtQuick 2.14; Node { id: "node${nodes.length}"; x: ${Math.random() * 300 + 200}; y: ${Math.random() * 200 + 150}; text: "${text}" }`, controller); nodes.push(newNode); connectionCanvas.requestPaint(); } // 添加子节点 function addChildNode(parentId, text) { var parentNode = getNodeById(parentId); if (!parentNode) return; var newNode = Qt.createQmlObject( `import QtQuick 2.14; Node { id: "node${nodes.length}"; x: ${parentNode.x + 150}; y: ${parentNode.y + Math.random() * 100 - 50}; text: "${text}" }`, controller); nodes.push(newNode); // 添加连接 var conn = Qt.createQmlObject( `import QtQuick 2.14; Connection { fromId: "${parentId}"; toId: "node${nodes.length-1}" }`, controller); connections.push(conn); connectionCanvas.requestPaint(); } // 根据ID查找节点 function getNodeById(id) { for (var i = 0; i < nodes.length; i++) { if (nodes[i].id === id) return nodes[i]; } return null; } // 更新节点位置 function updateNodePosition(id, newX, newY) { for (var i = 0; i < nodes.length; i++) { if (nodes[i].id === id) { nodes[i].x = newX; nodes[i].y = newY; break; } } } } // 节点对象定义 QtObject { id: nodeMeta property string id property real x property real y property string text } // 连接关系定义 QtObject { id: connectionMeta property string fromId property string toId } } ``` ### 关键代码注释说明 1. **Canvas 绘制核心逻辑**: - `quadraticCurveTo()` 函数实现二次贝塞尔曲线连接,模拟思维导图的分支效果 - 控制点计算 `controlX/Y` 动态调整曲线曲率(可修改 -50 值调整弯曲度) - `requestPaint()` 方法触发画布重绘,实时更新连线位置[^1] 2. **数据结构设计**: ```qml // 节点数据结构 QtObject { id: nodeMeta property string id // 唯一标识符 property real x // X坐标 property real y // Y坐标 property string text // 显示文本 } // 连接关系 QtObject { id: connectionMeta property string fromId // 起始节点ID property string toId // 目标节点ID } ``` 3. **动态节点管理**: - `Repeater` 组件根据 nodes 模型动态创建节点 - `createQmlObject()` 动态生成新节点(需要导入 `QtQml 2.0`) - 节点拖动时实时更新位置并重绘连线 4. **交互功能**: - 左键拖动节点:更新节点位置并重绘连接线 - 右键单击节点:添加子节点并创建新连接 - 工具栏按钮:添加新的根节点 5. **性能优化**: - 设置 `renderTarget: Canvas.Image` 启用硬件加速 - 使用 `MouseArea` 的 `containsPress` 替代 `pressed` 提升响应速度 - 增量重绘而非全画布刷新 ### 高级功能扩展建议 1. **键盘导航支持**: ```qml // 在Window添加Keys处理 Keys.onPressed: { if (event.key === Qt.Key_Plus) { zoomIn(); } else if (event.key === Qt.Key_Minus) { zoomOut(); } } function zoomIn() { // 实现画布放大 } function zoomOut() { // 实现画布缩小 } ``` 2. **文本编辑功能**: ```qml // 在节点元素内添加TextEdit TextEdit { visible: modelData.isEditing anchors.fill: parent text: modelData.text onEditingFinished: { modelData.text = text; modelData.isEditing = false; } } ``` 3. **使用 QtQuick.Shape 替代 Canvas(5.10+)**: ```qml Shape { ShapePath { fillColor: "transparent" strokeColor: "#3498db" strokeWidth: 2 // 使用PathQuad绘制贝塞尔曲线 PathQuad { x: toNode.x y: toNode.y controlX: controlX controlY: controlY } } } ``` 4. **实现主题切换**: ```qml // 主题管理器 ThemeManager { id: theme currentTheme: "light" } // 在绘制函数中使用 ctx.strokeStyle = theme.connectionColor ``` ### 运行环境要求 1. Qt 5.14+(支持最新的 QML 特性) 2. 启用 `Canvas` 模块(默认包含) 3. 建议使用 OpenGL 后端以获得最佳性能: ``` QQuickWindow::setSceneGraphBackend(QSGRendererInterface::OpenGL); ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一去丶二三里

有收获,再打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值