组件是可重用的元素。QML提供了不同的方法来创建组件。目前我们重点关注最简单的形式—基于文件的组件。通过在文件中放置 QML 元素并为文件指定元素名称(例如 Button.qml)来创建基于文件的组件。您可以像使用 Qt Quick 模块中的所有其他元素一样使用该组件。在我们的例子中,你会在你的代码中使用它作为 Button { ... }
    例如,让我们创建一个包含文本组件鼠标区域的矩形。我们的目的很简单,实现一个简单的类似按钮的功能。

    1. Rectangle { // our inlined button ui
    2. id: button
    3. x: 12; y: 12
    4. width: 116; height: 26
    5. color: "lightsteelblue"
    6. border.color: "slategrey"
    7. Text {
    8. anchors.centerIn: parent
    9. text: "Start"
    10. }
    11. MouseArea {
    12. anchors.fill: parent
    13. onClicked: {
    14. status.text = "Button clicked!"
    15. }
    16. }
    17. }
    18. Text { // text changes when button was clicked
    19. id: status
    20. x: 12; y: 76
    21. width: 116; height: 26
    22. text: "waiting ..."
    23. horizontalAlignment: Text.AlignHCenter
    24. }

    UI看起来差不多,在第一张图片中,UI处于初始状态,而在第二张图片中,按钮已经被单击。
    动画.gif
    现在我们的任务是将按钮UI提取到可重用组件中。为此,我们应该为按钮考虑一个可行的API,你可以想象别人应该如何使用你的按钮,以下是我的想法:

    1. // minimal API for a button
    2. Button {
    3. text: "Click Me"
    4. onClicked: { /* do something */ }
    5. }

    我想使用文本属性设置文本,并实现我自己的点击处理程序。此外,我希望按钮有一个合理的初始大小,我可以覆盖它(例如:width: 240)。要实现此功能,我们会创建一个Button.qml文件,并在内部复制我们的按钮UI代码。此外,我们需要导出用户可能想要在根级别更改的属性。

    1. // Button.qml
    2. import QtQuick
    3. Rectangle {
    4. id: root
    5. // export button properties
    6. property alias text: label.text
    7. signal clicked
    8. width: 116; height: 26
    9. color: "lightsteelblue"
    10. border.color: "slategrey"
    11. Text {
    12. id: label
    13. anchors.centerIn: parent
    14. text: "Start"
    15. }
    16. MouseArea {
    17. anchors.fill: parent
    18. onClicked: {
    19. root.clicked()
    20. }
    21. }
    22. }

    我们已经在根级导出了text属性和点击信号。通常,我们将根元素命名为root是为了更容易引用它。我们使用QML的别名特性,这是一种将嵌套的QML元素中的属性导出到根级别,并使其在外部可以使用的方法。还有很重要的一点我们要知道,其他组件只能从该文件根级属性访问对外属性。
    要使用我们的新Button 元素,我们可以简单地在文件中声明它,所以前面的例子会变得有点简化。

    1. Button { // our Button component
    2. id: button
    3. x: 12; y: 12
    4. text: "Start"
    5. onClicked: {
    6. status.text = "Button clicked!"
    7. }
    8. }
    9. Text { // text changes when button was clicked
    10. id: status
    11. x: 12; y: 76
    12. width: 116; height: 26
    13. text: "waiting ..."
    14. horizontalAlignment: Text.AlignHCenter
    15. }

    现在,您只需使用 Button { ... } 即可在 UI 中使用任意数量的按钮。真正的按钮可能更复杂,例如在单击时提供反馈或显示的丰富。
    动画.gif :::success 如果愿意,甚至可以更进一步,使用Item作为根元素。这可以防止用户改变我们设计的按钮的颜色,并能导出更多控制API。目标应该是导出最小的API。实际上,这意味着我们需要将根矩形替换为Item,并使矩形成为根项目中的嵌套元素。 :::

    1. Item {
    2. id: root
    3. width: 116; height: 26
    4. property alias text: label.text
    5. signal clicked
    6. Rectangle {
    7. anchors.fill parent
    8. color: "lightsteelblue"
    9. border.color: "slategrey"
    10. }
    11. ...
    12. }

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