Компоненты QML
Компонент – это повторно используемый элемент. QML предоставляет различные способы создания компонентов. Сейчас мы рассмотрим только самую простую форму – компонент на базе файла. Компонент на базе файла создается путем помещения элемента QML в файл и присвоения этому файлу имени элемента (например, Button.qml). Вы можете использовать этот компонент, как и любой другой элемент из модуля Qt Quick. В нашем случае вы использовали бы его в своем коде как Button {...}
.
Например, давайте создадим прямоугольник, содержащий текстовый компонент и область обработки событий мыши. Это похоже на простую кнопку и для наших целей не должно быть более сложным.
Rectangle { // наш интерфейс встроенной кнопки
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 { // текст меняется при нажатии на кнопку
id: status
x: 12; y: 76
width: 116; height: 26
text: "waiting ..."
horizontalAlignment: Text.AlignHCenter
}
Пользовательский интерфейс будет выглядеть примерно так. На первом изображении пользовательский интерфейс находится в исходном состоянии, а на втором изображении после нажатия кнопки.
Теперь наша задача – извлечь пользовательский интерфейс кнопки в повторно используемый компонент. Для этого мы должны подумать о возможном API для нашей кнопки. Вы можете сделать это, представив, как кто-то другой должен использовать вашу кнопку. Вот что я придумал:
// минимальный API для кнопки
Button {
text: "Click Me"
onClicked: { /* сделать что-нибудь */ }
}
Я хотел бы установить текст с помощью свойства text
и реализовать свой собственный обработчик кликов. Кроме того, я ожидаю, что кнопка будет иметь разумный начальный размер, который я могу перезаписать (например, width: 240
).
Для этого мы создаем файл Button.qml и копируем внутрь наш пользовательский интерфейс кнопки. Кроме того, нам нужно экспортировать свойства, которые пользователь может захотеть изменить на корневом уровне.
// Button.qml
import QtQuick
Rectangle {
id: root
// экспорт свойств кнопки
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, который позволяет экспортировать свойства внутри вложенных элементов QML на корневой уровень и сделать их доступными для внешнего мира. Важно знать, что извне этого файла другие компоненты могут получить доступ только к свойствам корневого уровня.
Чтобы использовать наш новый элемент Button
, мы можем просто объявить его в нашем файле. Таким образом, предыдущий пример станет немного проще.
Button { // наш компонент Button
id: button
x: 12; y: 12
text: "Start"
onClicked: {
status.text = "Button clicked!"
}
}
Text { // текст меняется при нажатии на кнопку
id: status
x: 12; y: 76
width: 116; height: 26
text: "waiting ..."
horizontalAlignment: Text.AlignHCenter
}
Теперь вы можете использовать в своем пользовательском интерфейсе столько кнопок, сколько захотите, просто используя Button { ... }
. Настоящая кнопка может быть более сложной, например, обеспечивать обратную связь при нажатии или показывать более красивое оформление.
Совет
Если вы хотите, то можете пойти еще дальше и использовать Item
в качестве корневого элемента. Это не позволит пользователям изменять цвет кнопки, которую мы разработали, и дает нам больший контроль над экспортируемым API. Цель должна состоять в том, чтобы экспортировать минимальный API. На практике это означает, что нам нужно заменить корневой Rectangle
на Item
и сделать прямоугольник вложенным элементом в корневой элемент.
Item {
id: root
width: 116; height: 26
property alias text: label.text
signal clicked
Rectangle {
anchors.fill parent
color: "lightsteelblue"
border.color: "slategrey"
}
...
}
С помощью этой технологии можно легко создать целый ряд компонентов, доступных для повторного использования.