组件
组件是一个可重复使用的元素。QML 提供了多种创建组件的方法。目前,我们仅探讨最简单的形式------基于文件的组件。基于文件的组件是通过将 QML 元素放置在文件中,并为该文件赋予一个元素名称(例如 Button.qml )来创建的。你可以像使用 Qt Quick 模块中的其他元素一样使用该组件。在我们的示例中,你可以在代码中将其作为 Button { ... } 使用。
例如,让我们创建一个包含文本组件和鼠标区域(Mouse Area)的矩形。这就像一个简单的按钮,对于我们的目的来说,不需要更复杂的设计。
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
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()
}
}
}
我们在根级导出了 text 属性和 clicked 信号。通常我们将根元素命名为 root,以便于引用。我们使用了 QML 的 alias 特性,这是一种将嵌套 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 { ... } 就可以在界面中随心所欲地使用任意数量的按钮。一个真实的按钮可能会更复杂,例如在点击时提供反馈,或者展示更精美的装饰。
如果你愿意,甚至可以更进一步,使用 Item 作为根元素。这可以防止用户更改我们设计的按钮颜色,并让我们对导出的 API 拥有更多控制权。目标应该是导出最小化的 API。在实践中,这意味着我们需要将根 Rectangle 替换为 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"
}
...
}
通过这种技术,可以轻松创建出一整套可重用的组件。