# 组件
组件是可重用的元素。 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"
}
...
}
使用这种技术,可以轻松创建一系列可重用的组件。