Qt5 Cadaques - Qt Quick/QML 编程全指南
一本开源的 Qt5 / Qt Quick / QML 编程教程,从基础语法到高级渲染特效、C++ 扩展和 Python 绑定,内容全面且实战导向。
书籍概览
- 作者: Jonas Ryannel, Johan Thelin
- 版本: Release master(基于 Qt 5.12,2020 年 12 月更新)
- 定位: 从入门到进阶的 Qt Quick/QML 实战教程
- 特点: 每章都有配套代码示例,循序渐进,强调动手实践
- 章节结构: 21 章,从 QML 基础到 C++/Python 扩展,覆盖移动应用开发
核心知识体系
一、Qt5 基础架构
1. Qt 模块体系
Qt5 分为两大模块组:
Qt Essentials(核心必需模块):
QtCore— 核心非图形类,被其他模块依赖QtGUI— GUI 基础类,包含 OpenGLQtQml— QML 和 JavaScript 语言支持QtQuick— 声明式框架,构建高度动态的自定义 UIQt Quick Controls 2— 轻量级 QML 控件(按钮、标签、滑块等)Qt Quick Layouts— 布局管理器QtNetwork— 网络编程QtMultimedia— 音视频/相机QtSQL— 数据库集成QtWidgets— 传统 C++ Widget 库
Qt Add-On(附加模块):
- Qt 3D — 3D 图形编程
- Qt Bluetooth — 蓝牙
- Qt Canvas 3D — 类 OpenGL 的 3D 绘制
- Qt Graphical Effects — 图形特效
- Qt Location — 地图与导航
- Qt Sensors — 传感器
- Qt Purchasing — 应用内购买
2. Qt Project 与开源社区
Qt 是一个精英治理(meritocratic)的开源社区,最大贡献者是 The Qt Company(同时持有商业授权)。
二、QML 语言核心
1. QML 语法基础
QML 是一种声明式语言,类似 HTML,但专为构建动态 UI 设计。
核心概念:
- 元素 (Element): QML 的基本构建块,如
Rectangle、Text、Image - 属性 (Property): 键值对,有明确类型,如
width: 100、color: "#FF0000" - id: 特殊标识符,用于在文档内引用元素,不可在运行时修改
- 锚定 (Anchors): 声明元素间的几何关系(left/right/top/bottom/centerIn/fill 等)
- 信号与槽 (Signals & Slots): 事件驱动机制,命名惯例
on<SignalName>
属性的 9 种形态:
id— 文档内唯一标识符(非字符串,是语法关键字)- 普通赋值 —
width: 100 - 属性绑定 (Binding) —
height: 2 * width,依赖变化时自动更新(“契约式”) - 自定义属性 —
property int times: 24 - 属性别名 (Alias) —
property alias anotherTimes: thisLabel.times,用于向外暴露内部属性 - 字符串拼接绑定 —
text: "Greetings " + times - 分组属性 —
font.family: "Ubuntu",结构化属性分组 - 附加属性 —
KeyNavigation.tab: otherLabel,全局属性附加到元素上 - 属性变更信号处理器 —
onHeightChanged: console.log(height)
重要警告: QML 的绑定(
:)和 JavaScript 赋值(=)有本质区别。绑定是”终身契约”,一旦用 JS 赋值给同一属性,绑定就被破坏了!这是 QML 新手最常见的坑。
2. 基本元素
Item(所有视觉元素的基类):
- 几何属性:
x,y,width,height,z - 布局: anchors(锚定系统)
- 按键:
focus,Key,KeyNavigation - 变换:
scale,rotation,transformOrigin - 视觉:
opacity,visible,clip,smooth - 状态:
states,transitions
常用视觉元素:
Rectangle— 矩形,支持填充色、边框、圆角(radius)Text— 文本,支持富文本、换行、省略Image— 图片,支持 fillMode(PreserveAspectFit / PreserveAspectCrop 等)MouseArea— 鼠标/触摸交互区域,onClicked等信号
3. 组件 (Components)
QML 支持自定义可复用组件。一个 .qml 文件就是一个组件,文件名即组件名(首字母大写)。通过 property alias 向外暴露内部属性。
三、动画与状态
1. 动画系统
QML 提供丰富的动画类型,核心是 Animation 及其子类:
- PropertyAnimation / NumberAnimation — 数值属性动画
- ColorAnimation — 颜色动画
- RotationAnimation — 旋转动画(处理 360° 环绕)
- PathAnimation — 沿路径运动
三种使用动画的方式:
- Behavior on
— 属性变化时自动触发动画(最常用) - 直接启动 —
animation.start()手动控制 - Transition — 状态切换时的过渡动画
2. 状态与过渡 (States & Transitions)
states列表定义不同状态State包含PropertyChanges,描述状态间的属性差异transitions定义状态切换时的动画过渡when条件触发状态切换
四、Qt Quick Controls 2
提供标准 UI 控件库:按钮、标签、滑块、输入框、下拉菜单等。特点:轻量、高性能、支持多种样式(Material、Universal、Imagine 等)。
Imagine Style: 基于图像的样式系统,可以完全自定义控件外观,适合打造品牌化 UI。
五、Model-View-Delegate 架构
Qt Quick 的列表/视图采用经典的 M-V-D 模式:
- Model (模型): 数据源,可以是简单数组、ListModel、C++ 自定义模型
- View (视图): 显示数据的容器(ListView、GridView、Repeater 等)
- Delegate (委托): 定义每个数据项如何渲染,是模型的可视化表达
关键概念:
ListView— 纵向/横向滚动列表GridView— 网格视图Repeater— 非滚动的重复器- 动态视图支持懒加载,只创建可见区域的 delegate
- delegate 中可直接访问 model 的角色数据
六、高级图形
1. Canvas 元素
提供类似 HTML5 Canvas 的 2D 绘制 API,支持:
- 路径、渐变、阴影、图像
- 变换(平移/旋转/缩放)
- 合成模式(Composition Modes)
- 像素缓冲区(像素级操作)
- 可从 HTML5 Canvas 迁移过来
2. 粒子系统 (Particle System)
用于创建烟、火、火花等动态视觉效果:
ParticleSystem— 粒子系统管理器Emitter— 粒子发射器ParticlePainter/ImageParticle— 粒子渲染器- 影响器:
Gravity(重力)、Friction(摩擦)、Turbulence(紊流)、Wander(漫游) - 粒子组与组转换 — 实现火箭爆炸等多阶段效果
3. 着色器特效 (Shader Effects)
通过 ShaderEffect 和 ShaderEffectSource 直接调用 GPU 的 OpenGL 着色器:
- 顶点着色器 (Vertex Shader): 操作多边形顶点,控制 3D 变换
- 片段着色器 (Fragment Shader): 逐像素计算颜色,实现扭曲、波纹等特效
- 使用 GLSL 语言编写,通过 QML 属性与着色器交互
- Qt 提供
QtGraphicalEffects模块内置多种特效(模糊、发光、色相等)
七、多媒体与网络
1. 多媒体
MediaPlayer— 播放音频/视频SoundEffect— 短音效VideoOutput— 视频渲染Camera— 相机捕获
2. 网络编程
HTTP 请求: 使用 XMLHttpRequest(和浏览器 API 一致)发起 GET/POST/PUT/DELETE 请求
REST API 交互模式:
- 将 API 封装为 JS 服务模块(如
colorservice.js) - 使用
XMLHttpRequest+ JSON 解析 - 封装 CRUD 操作接口供 QML 调用
其他网络能力:
XmlListModel— XML 数据模型- WebSockets — 实时双向通信
- OAuth — 第三方登录授权
- 本地文件访问
八、存储
- Settings: 键值对持久化(类似 QSettings)
- LocalStorage / SQL: 嵌入式 SQLite 数据库
- 其他存储 API
九、动态 QML
- 动态加载组件:
Loader元素、Qt.createComponent()+createObject() - 动态创建/销毁对象: 运行时生成 QML 对象
- 跟踪动态对象: 管理动态创建的对象生命周期
十、JavaScript 与 QML
QML 深度集成 JavaScript:
- 属性绑定使用 JS 表达式
- 信号处理器中写 JS 代码
- 可定义 JS 函数
- 支持 JS 模块导入
- 注意:JS 赋值会破坏 QML 绑定(见前文警告)
十一、Qt 与 C++
1. QObject 基石
QObject 是 Qt 对象系统的基类,提供两大能力:
- 内省 (Introspection): 知道自己的类名、属性、方法、信号
- 内存管理: 父子对象树,父对象销毁时自动销毁子对象
Q_OBJECT 宏: 启用元对象系统,必须放在类的私有区开头
Q_PROPERTY 宏: 声明属性,格式:
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)- READ — 读取函数
- WRITE — 写入函数(可选,只读属性没有)
- NOTIFY — 变更通知信号(QML 绑定依赖它)
信号与槽: Qt 的核心通信机制,松耦合。用 connect() 连接。
小技巧:
Q_GADGET宏是 Q_OBJECT 的轻量版,可用于非 QObject 派生类暴露属性和可调用方法,但不能有信号。
2. 构建系统
qmake: Qt 原生构建系统,使用 .pro 项目文件
QT += qml quick— 添加 QML/Quick 模块TEMPLATE = app / lib / subdirs— 应用/库/子目录- 支持 scope(平台条件编译):
unix { ... }、macx { ... } - 支持 shadow build(源码外构建)
CMake: 跨平台构建系统,适合大型项目
find_package(Qt5Core)— 查找 Qt 模块CMAKE_AUTOMOC ON— 自动调用 MOCtarget_link_libraries(target Qt5::Core)— 链接 Qt 库
3. 扩展 QML 与 C++ 插件
可以用 C++ 编写自定义 QML 类型和插件:
- 继承
QQmlExtensionPlugin编写插件 - 在
qmldir文件中注册插件 - QML 运行时动态加载
典型示例: FileIO 插件——在 QML 中读写本地文件
十二、Felgo 框架
Felgo(原 V-Play)是基于 Qt 的跨平台应用/游戏开发框架:
核心特性:
- 热重载 (QML Hot Reloading) — 代码修改即时生效
- 密度无关像素 —
dp()用于尺寸,sp()用于字体 - 自适应导航 — 桌面显示侧边栏,移动显示底部 Tab
- 丰富的内置组件:
Navigation,NavigationStack,ListPage,SimpleRow等 - 大量插件: 广告、内购、通知、分析、Firebase、云存储、AR 等
开发体验: 内置 Live Client,支持手机端实时预览
十三、Qt for Python (PySide2)
Qt 的官方 Python 绑定,让 Python 开发者使用 Qt:
基本用法:
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(QUrl("main.qml"))
app.exec_()向 QML 暴露 Python 对象:
- 继承
QObject - 用
Signal(类型)声明信号 - 用
@Slot()装饰器声明槽 - 通过
engine.rootContext().setContextProperty("name", obj)暴露为全局变量
已知限制:
- Python 信号的参数名无法传递到 QML(需要 workaround)
- Python 中没有 invokable 概念,所有可调用方法必须是槽
关键概念速查
| 概念 | 说明 |
|---|---|
| 属性绑定 | height: 2 * width,响应式更新,是契约而非一次性赋值 |
| 锚定系统 | anchors 声明元素间几何关系,替代手动坐标计算 |
| 信号槽 | Qt 的事件驱动核心,松耦合通信 |
| M-V-D | Model-View-Delegate,数据与视图分离 |
| QObject | Qt 对象系统基类,提供内省和内存管理 |
| MOC | 元对象编译器,处理 Q_OBJECT 等宏生成 C++ 代码 |
| ShaderEffect | GPU 着色器,实现高级视觉特效 |
| Behavior on | 属性变化自动触发动画的便捷语法 |
| property alias | 组件向外暴露内部属性的方式 |
| 隐式共享 | QString 等 Qt 类的写时拷贝内存优化 |
学习路径建议
- 入门: 第 1-4 章 — 认识 Qt5,安装环境,QML 语法基础
- 进阶: 第 5-7 章 — 动画、控件、MVD 模式
- 实战: 第 8 章 — 用 Felgo 做一个完整的消息应用
- 高级图形: 第 9-11 章 — Canvas、粒子系统、着色器
- 全栈能力: 第 12-15 章 — 多媒体、网络、存储、动态 QML
- 性能扩展: 第 16-18 章 — JS 集成、C++ 扩展、编写 QML 插件
- 生态: 第 19-20 章 — Felgo 插件、Qt for Python
与其他知识的关联
个人备注
- 这本书是开源免费的,可以作为 Qt Quick/QML 的入门首选教程
- Felgo 部分有较强的商业导向,但热重载和密度无关像素的设计思想值得借鉴
- 如果做移动应用,Felgo 相比原生 Qt Quick 能节省大量样板代码
- C++ 扩展章节(17-18章)是理解 Qt 底层的关键,值得深入