组件是可重用的元素。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
Button {
text: "Click Me"
onClicked: { /* do something */ }
}
我想使用文本属性设置文本,并实现我自己的点击处理程序。此外,我希望按钮有一个合理的初始大小,我可以覆盖它(例如: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属性和点击信号。通常,我们将根元素命名为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 中使用任意数量的按钮。真正的按钮可能更复杂,例如在单击时提供反馈或显示的丰富。
:::success
如果愿意,甚至可以更进一步,使用Item
作为根元素。这可以防止用户改变我们设计的按钮的颜色,并能导出更多控制API。目标应该是导出最小的API。实际上,这意味着我们需要将根矩形替换为Item
,并使矩形成为根项目中的嵌套元素。
:::
Item {
id: root
width: 116; height: 26
property alias text: label.text
signal clicked
Rectangle {
anchors.fill parent
color: "lightsteelblue"
border.color: "slategrey"
}
...
}
使用这种技术,可以轻松创建一系列可重用的组件。