本文翻译自
https://www.vikingsoftware.com/a-good-qml-file/
什么样的Qml文件(通常称为组件)是一个高质量的文件?
让我们看看示例1:
1 | import QtQuick 2.9 |
再看看示例2:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37import QtQuick 2.9
/**
Simple push button like component
No support for theming or icons are provided
*/
Item {
id: root
/// The text on the button
property alias text: textItem.text
/// The signal is emitted when the user clicked on the button
signal clicked()
implicitWidth: textItem.implicitWidth
implicitHeight: textItem.implicitHeight
width: implicitWidth
height: implicitHeight
Rectangle {
id: backround
anchors.fill: parent
color: "lightgray"
}
Text {
id: textItem
anchors.centerIn: parent
}
MouseArea {
id: clickArea
anchors.fill: parent
onClicked: {
root.clicked();
}
}
QtObject {
id: internal
function foo() {
}
}
}
我希望您认同示例2更清晰、更易于使用。但是,让我们来看看它们有什么不同之处:
- QML文件应该始终具有相同的顺序结构:
1
2
31. 应该从公共API(如属性、信号和函数)开始;
2. 再到设置的派生属性;
3. 最后是它包含的项。
其思想是,如果有人想要使用该组件,他只需要查看顶部部分。当你浏览代码的时候,它会变得简单很多。
- 应该对公共API文档化(注释),就像所有高质量的代码一样。
- 文件所包含的根控件,以“root”作为其id。 它是文件中通常使用最多的id。 如果总是使用相同的id,就会更容易。
- 所有控件都有一个id集。 我这么做是因为让描述该控件的名称。
- 控件的id总是在第一行。
控件不应该包含一些与其他不相关的组件,应该是纯粹的组合关系。
1
示例1中根控件MouseArea包含了一些Rectangle和Text与原本意思不相符的东西。
设置隐式大小并用作默认大小。 隐式大小主要用于动态布局。 使用时可以覆盖实际大小。 做为一个默认值使用会很方便。 相比之下,在一个不好的示例1中,组件已经假定它将如何使用默认大小并在这种情况下通过设置锚点。
- 应隐藏不应从外部使用的属性和函数。 我这样做是通过将它们移动到我称之为内部的QtObject(对于我来说,类似于Qt C ++中的d指针)。 所以函数由
internal.foo()
而不是root.foo()
或只是foo()
调用。 另一种选择是使用双下划线(此处为__foo()
)来作为私有属性和函数的名称。 - 对于text属性,使用别名来保存重复,内存和绑定工作。
示例2稍微多一些工作。 但像往常一样,质量代码增加了一些额外的工作量。 一旦习惯了它,那就不是那么多了。 所以这个简短的列表已经涵盖了一个易于使用的编写良好的QML文件的许多方面。 遵循这些想法将有助于生成可重用且更易维护的QML组件。
译者总结
好的代码 | 好的示例 | 不好的示例 |
---|---|---|
文件相同的顺序结构 | 示例2中属性->信号->函数->其他 | 示例1中自定义属性随便放 |
关键部分需要注释 | 例子2中关键部分属性与信号都有注释 | 例子1无注释难阅读 |
控件应该有一个id名字且明确 | 示例2 | 示例1 |
控件id应该放在第一行 | 示例2 | 示例1 |
功能明确且单一的 | 示例2 | 示例1中MouseArea包含多个与自己不相关的内容 |
使用隐式大小 | 示例2中使用了implicitWidth属性 | 示例1中直接设置width |
锚点应由上层设置 | 示例2 | 示例1内部设置了锚点会导致意想不到的情况 |
隐藏私有属性和函数或使用双下划线标记 | 示例2中使用QtObject来存放私有属性 | 示例1 |
能使用别名的就别重新定义变量 | 示例2中property alias text |
示例1中button.text |