# 组件

组件是可重用的元素。 QML提供了不同的方式来创建组件。 目前,我们将只了解最简单的形式——基于文件的组件。 通过在文件中放置QML元素,并用文件名指定元素名称(例如Button.qml),创建基于文件的组件。 可以像使用Qt Quick模块中的所有其他元素一样使用该组件。 在例子中,会在代码中如同Button { ... }使用它。

例如,创建一个包含文本组件和鼠标区域的矩形。 这类似于一个简单的按钮,对于我们的目的来说已经足够。

Rectangle { // our inlined button ui
    id: button
    x: 12; y: 12
    width: 116; height: 26
    color: "lightsteelblue"
    border.color: "slategrey"
    Text {
        anchors.centerIn: parent
        text: "Start"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            status.text = "Button clicked!"
        }
    }
}

Text { // text changes when button was clicked
    id: status
    x: 12; y: 76
    width: 116; height: 26
    text: "waiting ..."
    horizontalAlignment: Text.AlignHCenter
}

UI将与此类似。 在第一个图像中,UI处于初始状态;在第二个图像中,按钮已经被单击。

现在的任务是将按钮UI提取到一个可重用的组件中。 为此,应该为按钮考虑一个可能的API,可以通过想象其他人应该如何使用按钮来完成。 有如下假设:

// minimal API for a button
// 按钮的最小API
Button {
    text: "Click Me"
    onClicked: { /* do something */ }
}

想使用text属性设置文本并实现自己的点击处理器。 另外,希望按钮有一个合理的初始大小,并可以覆盖它(例如,使用width: 240)。

为了实现这一点,创建了一个Button.qml文件并将按钮UI复制到里面。 此外,需要导出用户可能希望在根级别更改的属性。

// Button.qml

import QtQuick

Rectangle {
    id: root
    // export button properties
    property alias text: label.text
    signal clicked

    width: 116; height: 26
    color: "lightsteelblue"
    border.color: "slategrey"

    Text {
        id: label
        anchors.centerIn: parent
        text: "Start"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            root.clicked()
        }
    }
}

已经在根级别导出了文本属性和点击信号。 通常,将根元素命名为root以使其更容易引用。 使用QML的别名特性,这是一种将嵌套QML元素内的属性导出到根级别并使其可供外部世界使用的方法。 重要的是要知道,其他组件只能从该文件外部访问根级别的属性。

要使用新Button元素,可以简单地在文件中声明它。 所以前面的例子会变得有点简化。

Button { // our Button component
    id: button
    x: 12; y: 12
    text: "Start"
    onClicked: {
        status.text = "Button clicked!"
    }
}

Text { // text changes when button was clicked
    id: status
    x: 12; y: 76
    width: 116; height: 26
    text: "waiting ..."
    horizontalAlignment: Text.AlignHCenter
}

现在,只需使用Button { ... }即可在UI中使用任意数量的按钮。 真正的按钮可能更复杂,例如在单击时提供反馈或添加显示上更好的装饰。

提示

如果愿意,甚至可以更进一步,使用Item作为根元素。 这可以防止用户更改设计的按钮颜色,并为提供对导出API的更多控制。 目标应该是导出最小的API。 实际上,这意味着需要用Item替换根Rectangle,并使矩形成为根项中的嵌套元素。

Item {
    id: root
    width: 116; height: 26

    property alias text: label.text
    signal clicked

    Rectangle {
        anchors.fill parent
        color: "lightsteelblue"
        border.color: "slategrey"
    }
    ...
}

使用这种技术,可以轻松创建一系列可重用的组件。

最后更新: 11/26/2021, 8:10:04 AM