属性的命名

注: 以下做法只是为了尽量避免和 QML 内置属性重命, 以及为了更方便开发者通过名字就能确定它的一些特征.

id 属性使用 "_xxx" 作为前缀, 并仅限于当前 qml 文件的引用

_xxx 下划线开头的变量用于暗示这是一个 "私有" 变量, 请避免让它被外部文件直接访问.

property 定义的 "public" 变量使用 "p_xxx" 作为前缀

property 定义的 "private" 变量使用 "__xxx" 作为前缀

objectName 属性使用 "{相对路径}#{id}" 的形式, 其中 id 必须被先声明

property 优先使用 alias 变量

property 定义的 alias 变量, 如果引用的是对象的 id, 则用 "obj_Xxx" 作为前缀, 且使用大驼峰式写法

函数和信号使用 "fn_xxx" 作为前缀

属性的书写顺序

  1. id 始终位于第一行, objectName 始终位于第二行

  2. 以下属性按照指定顺序置顶显示: id > objectName > name > source (常见于 Loader 对象) > target (常见于 State 对象) > 其他内建属性 (按照字母表顺序) > 自定义属性 (按照字母表顺序).

  3. 对于关联性强的元素, 可以合并到一行书写 (在单行内的属性书写顺序无需按照字母表顺序)

视图/模型分离的设计

原则: QML 只负责布局和 UI 的呈现, 模型 (数据) 以及模型交互的逻辑全部由 Python 实现.

实践类问题: 我在 QML 中有一个 Grid 对象, 我想要通过 Python 向里面动态地添加 MyItem 对象, 我该怎么做?

具体的实现讲解见这篇文章: TODO. 这里从设计原则的角度说一下应该怎么做.

首先, 这个思路是不可取的: Python 通过 engine 获取到 Grid 对象, 并操作 Grid 的 add 方法, 渲染并插入一个 MyItem 对象.

这个思路的问题有两个:

  1. 经我个人实验, "操作 Grid 的 add 方法" 这一步似乎无法在 Python 中实现, Qt 没有提供此方法, 网上也找不到解答
  2. 这不符合视图/模型分离的设计原则, 我们在 Python 中操作 Grid, 为其插入 MyItem, 这个工作属于 UI 操作范畴, 本应该交由 QML 引擎实现. 所以正确的做法是我们 Python 只操作 Grid 的数据模型, 使模型中新增一个 MyItem 的数据, 然后 QML 根据模型变动在布局中渲染出一个 MyItem

所以, 一个可参考的思路是这样的:

QML 端: Grid 内套一个 Repeater 对象 (因为 Repeater 有 model 属性), Repeater 的 delegate 属性 (代理对象) 设为 MyItem

Python 端: Python 通过 engine 获取到 Repeater 对象, 对其 model 进行操作, 插入一条 MyItem 的数据. QML 自动完成 UI 的更新.