注: 以下做法只是为了尽量避免和 QML 内置属性重命, 以及为了更方便开发者通过名字就能确定它的一些特征.
_xxx
下划线开头的变量用于暗示这是一个 "私有" 变量, 请避免让它被外部文件直接访问.
xxxxxxxxxx
1// === A.qml ===
2import QtQuick 2.15
3
4Item {
5property alias p_size: _txt.font.pixelSize
6property alias p_text: _txt.text
7Text { id: _txt }
8}
9
10// === B.qml ===
11import QtQuick 2.15
12
13Item {
14A {
15// 在 B.qml 中, 是访问不到 A.qml 的 id 为 _txt 的对象的. 这也是我们希望
16// 看到的结果.
17// 不过我们可以访问和修改 p_size 和 p_text.
18p_size: 18
19p_text: "hello world"
20}
21}
22
xxxxxxxxxx
61import QtQuick 2.15
2
3Item {
4property string p_text: ""
5Text { text: p_text }
6}
x1import QtQuick 2.15
2
3Item {
4property bool __active: false // `__active` 只允许在该文件内使用, 请不要在
5// 外部调用时修改它.
6
7Rectangle {
8color: __active ? "white" : "gray"
9width: 100; height: 100
10
11MouseArea {
12anchors.fill: parent
13onClicked: {
14__active = !__active
15}
16}
17}
18}
19
xxxxxxxxxx
1// === D:/workspace/my_prj/ui/page1/Element.qml ===
2import QtQuick 2.15
3
4Item {
5id: _root
6// 相对路径是相对于当前项目 (my_prj) 的路径.
7objectName: "ui/page1/Element.qml#_root"
8
9Text {
10id: _txt
11objectName: "ui/page1/Element.qml#_txt"
12text: ""
13}
14}
xxxxxxxxxx
171// === A.qml ===
2import QtQuick 2.15
3
4Item {
5// 推荐
6property alias p_text1: _txt1.text
7Text {
8id: _txt1
9}
10
11// 不推荐
12property string p_text2: ""
13Text {
14id: _txt2
15text: p_text2
16}
17}
18
x1// === A.qml ===
2import QtQuick 2.15
3
4Item {
5property alias obj_Text: _txt
6
7Text {
8id: _txt
9}
10}
11
12// === B.qml ===
13import QtQuick 2.15
14
15Item {
16A {
17p_text: "hello world"
18
19// 在 B.qml 中, 不能直接访问 A.qml 的 id 为 _txt 的对象, 但可以通过
20// obj_Text 访问到它.
21obj_Text { // 这里相当于引用了 A.Item.Text 对象.
22font.bold: true
23}
24}
25}
26
xxxxxxxxxx
381// === A.qml ===
2import QtQuick 2.15
3
4Rectangle {
5id: _rect
6color: "white"
7width: 100; height: 100
8
9signal fn_clicked(string color)
10
11MouseArea {
12onClicked: {
13fn_clicked(_rect.color)
14}
15}
16}
17
18// === B.qml ===
19import QtQuick 2.15
20
21Item {
22width: 500; height: 500
23
24function fn_showColor(color) {
25_txt.text = color // 当点击 A 对象, 会使 _txt 对象的文字显示为 A 的颜色.
26}
27
28A {
29fn_clicked.connect(fn_showColor)
30}
31
32Text {
33id: _txt
34anchors.centerIn: parent
35text: "what's the color?"
36}
37}
38
id 始终位于第一行, objectName 始终位于第二行
xxxxxxxxxx
1import QtQuick 2.15
2
3Text {
4id: _txt
5objectName: "my_txt"
6}
以下属性按照指定顺序置顶显示: id > objectName > name > source (常见于 Loader 对象) > target (常见于 State 对象) > 其他内建属性 (按照字母表顺序) > 自定义属性 (按照字母表顺序).
x1import QtQuick 2.15
2
3Rectangle {
4id: _root
5objectName: "my_item"
6anchors.left: parent
7anchors.margins: 12
8anchors.top: parent
9
10property bool p_active: false
11
12states: [
13State {
14name: "defaultState"
15when: p_active
16PropertyChanges {
17target: _root
18color: "white"
19x: 10
20y: 10
21}
22}
23]
24
25Loader {
26id: _item1
27source: "./Items/Item1.qml"
28anchors.centerIn: parent
29}
30}
31
对于关联性强的元素, 可以合并到一行书写 (在单行内的属性书写顺序无需按照字母表顺序)
x1import QtQuick 2.15
2
3Rectangle {
4id: _rect
5color: "#FAFAFA"
6width: 100; height: 100 // 并到了一行书写.
7x: 10; y: 10; z: 1 // 并到了一行书写.
8
9property alias p_color: _rect.color
10property int p_index: 0
11property string p_text: ""
12signal fn_clicked(string color)
13
14Text {
15id: _txt
16anchors.centerIn: parent
17text: p_text
18
19font.bold: true
20font.family: "Microsoft YaHei UI"
21font.pixelSize: 18
22}
23}
原则: QML 只负责布局和 UI 的呈现, 模型 (数据) 以及模型交互的逻辑全部由 Python 实现.
具体的实现讲解见这篇文章: TODO. 这里从设计原则的角度说一下应该怎么做.
首先, 这个思路是不可取的: Python 通过 engine 获取到 Grid 对象, 并操作 Grid 的 add 方法, 渲染并插入一个 MyItem 对象.
这个思路的问题有两个:
所以, 一个可参考的思路是这样的:
QML 端: Grid 内套一个 Repeater 对象 (因为 Repeater 有 model 属性), Repeater 的 delegate 属性 (代理对象) 设为 MyItem
Python 端: Python 通过 engine 获取到 Repeater 对象, 对其 model 进行操作, 插入一条 MyItem 的数据. QML 自动完成 UI 的更新.