QML 编码规范

本文档包含我们在文档和示例中遵循的 QML 编码规范,并建议他人遵循。

QML 对象声明

在我们的文档和示例中,QML 对象属性始终按以下顺序结构

  • id
  • 属性声明
  • 信号声明
  • JavaScript 函数
  • 对象属性
  • 子对象

为了提高可读性,我们使用空行来分隔这些不同的部分。

例如,一个假设的photo 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
    }
}

必需属性

当需要定义在组件外部的数据时,通过使用必需属性来明确这一点。必需属性必须设置,否则组件的创建将失败。与无指定查找相比,它们更可取,因为它们更高效,并允许用户和工具推理外部属性的类型。此外,它们消除了组件必须对创建其环境的假设。

信号处理程序

在信号处理程序中处理参数时,使用明确命名的函数

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);
    }
}

© 2024 Qt公司有限公司。本文件中包含的文档贡献作品均属各自所有者的版权。本文件中提供的文档根据自由软件基金会发布的《GNU自由文档许可证》第1.3版条款获得许可。