QML 编码规范¶
代码风格约定
本文档包含我们在文档和示例中遵循并建议其他人遵循的QML编码规范。
QML 对象声明¶
在我们的文档和示例中,QML对象属性始终按照以下顺序进行结构化:
id
属性声明
信号声明
JavaScript 函数
对象属性
子对象
为了提高可读性,我们用空行分隔这些不同的部分。
例如,一个假设的照片 QML 对象将如下所示:
Rectangle { id: photo // id on the first line makes it easy to find an object property bool thumbnail: false // property declarations property alias image: photoImage.source signal clicked // signal declarations function doSomething(x) // javascript functions { return x + photoImage.width; } color: "gray" // object properties x: 20 // try to group related properties together y: 20 height: 150 width: { // large bindings if (photoImage.width > 200) { photoImage.width; } else { 200; } } states: [ State { name: "selected" PropertyChanges { target: border; color: "red" } } ] transitions: [ Transition { from: "" to: "selected" ColorAnimation { target: border; duration: 200 } } ] Rectangle { // child objects id: border anchors.centerIn: parent color: "white" Image { id: photoImage anchors.centerIn: parent } } }
分组属性¶
如果从一组属性中使用多个属性,考虑使用组表示法而不是点表示法,如果它能提高可读性。
例如,这个:
Rectangle { anchors.left: parent.left; anchors.top: parent.top; anchors.right: parent.right; anchors.leftMargin: 20 } Text { text: "hello" font.bold: true; font.italic: true; font.pixelSize: 20; font.capitalization: Font.AllUppercase }
可以这样写:
Rectangle { anchors { left: parent.left; top: parent.top; right: parent.right; leftMargin: 20 } } Text { text: "hello" font { bold: true; italic: true; pixelSize: 20; capitalization: Font.AllUppercase } }
不合格访问¶
为了提高可读性和性能,始终通过其ID显式引用父组件的属性:
Item { id: root property int rectangleWidth: 50 Rectangle { width: root.rectangleWidth } }
必需属性¶
当需要组件外部定义的数据时,通过使用Required Properties来明确这一点。必须设置必需的属性,否则组件的创建将失败。这些属性比未限定的查找更可取,因为它们性能更好,并且允许用户和工具推断外部属性的类型。此外,它们消除了组件对其创建环境的假设。
信号处理程序¶
在信号处理程序中处理参数时,使用明确命名的函数:
MouseArea { onClicked: event => { console.log(`${event.x},${event.y}`); } }
JavaScript 代码¶
如果脚本是单个表达式,我们建议将其内联编写:
Rectangle { color: "blue"; width: parent.width / 3 }
如果脚本只有几行,我们通常使用一个块:
Rectangle { color: "blue" width: { var w = parent.width / 3; console.debug(w); return w; } }
如果脚本超过几行或可以被不同的对象使用,我们建议创建一个函数并像这样调用它:
function calculateWidth(object : Item) : double { var w = object.width / 3; // ... // more javascript code // ... console.debug(w); return w; } Rectangle { color: "blue"; width: calculateWidth(parent) }
还请注意,建议为您的函数添加类型注释,以便更容易地推理和重构您的应用程序,因为参数和返回类型都可以从函数签名中立即看到。
对于较长的脚本,我们会将函数放在它们自己的JavaScript文件中,并像这样导入:
import "myscript.js" as Script Rectangle { color: "blue"; width: Script.calculateWidth(parent) }
如果代码超过一行并且因此在一个块中,我们使用分号来表示每个语句的结束:
MouseArea { anchors.fill: parent onClicked: event => { var scenePos = mapToItem(null, event.x, event.y); console.log("MouseArea was clicked at scene pos " + scenePos); } }