Атрибуты объекта QML
Каждый тип объекта QML имеет определённый набор атрибутов. Каждый экземпляр типа объекта создаётся с набором атрибутов, определённых для этого типа объекта. Существуют несколько различных типов атрибутов, которые могут быть заданы, и они описаны ниже.
Атрибуты в объявлениях объектов
Объявление объекта в документе QML определяет новый тип. Оно также объявляет иерархию объектов, которая будет проинициализирована, если будет создан экземпляр этого вновь определённого типа.
Следующий набор типов атрибутов QML-объектов:
- атрибут id
- атрибуты свойств
- атрибуты сигналов
- атрибуты обработчиков сигналов
- атрибуты методов
- присоединённые свойства и атрибуты присоединённых обработчиков сигналов
- атрибуты перечислений
Эти атрибуты подробно рассматриваются ниже.
Атрибут id
Каждый тип объекта QML имеет ровно один атрибут id. Этот атрибут предоставляется самим языком и не может быть переопределён или изменён каким-либо типом QML-объекта.
Значение может быть назначено атрибуту id экземпляра объекта, чтобы этот объект можно было идентифицировать и ссылаться на него другими объектами. Это значение id должно начинаться с маленькой буквы или нижнего подчёркивания и не может содержать символов, кроме букв, цифр и нижних подчёркиваний.
Ниже приведены объекты TextInput и Text. Значение атрибута id объекта TextInput установлено в «myTextInput». Объект Text устанавливает своё свойство text таким же, как свойство text объекта TextInput, ссылаясь на myTextInput.text. Теперь оба элемента будут отображать одинаковый текст:
import QtQuick 2.0
Column {
width: 200; height: 200
TextInput { id: myTextInput; text: "Hello World" }
Text { text: myTextInput.text }
} На объект можно сослаться по его атрибуту id из любой точки области видимости компонента, в которой он объявлен. Следовательно, значение id должно быть уникальным в рамках области видимости компонента. Дополнительную информацию см. в разделе Область видимости и разрешение имён.
После создания экземпляра объекта значение его атрибута id изменить нельзя. Хотя он может выглядеть как обычное свойство, атрибут id не является обычным атрибутом property, и для него применяются специальные семантики; например, получить доступ к myTextInput.id в приведённом выше примере нельзя.
Атрибуты свойств
Свойство — это атрибут объекта, которому можно присвоить статическое значение или привязать динамическое выражение. Значение свойства может считываться другими объектами. Как правило, его также может изменять другой объект, если конкретный тип QML этого явно не запретил для конкретного свойства.
Определение атрибутов свойств
Свойство может быть определено для типа в C++ путём регистрации Q_PROPERTY класса, который затем регистрируется в системе типов QML. В качестве альтернативы пользовательское свойство типа объекта может быть определено в объявлении объекта в документе QML с помощью следующего синтаксиса:
[default] property <propertyType> <propertyName>
Таким образом, объявление объекта может опубликовать определённое значение для внешних объектов или проще поддерживать некоторое внутреннее состояние.
Имена свойств должны начинаться с маленькой буквы и могут содержать только буквы, цифры и символы нижнего подчёркивания. Зарезервированные слова JavaScript не являются допустимыми именами свойств. Ключевое слово default является необязательным и изменяет семантику объявляемого свойства. Дополнительную информацию об атрибуте свойства default см. в следующей секции о свойствах по умолчанию.
Объявление пользовательского свойства подразумевает создание сигнала изменения значения для этого свойства, а также связанного обработчика сигнала с именем on<ИмяСвойства>Changed, где <ИмяСвойства> — это имя свойства с заглавной первой буквой.
Например, следующее объявление объекта определяет новый тип, который наследуется от базового типа Rectangle. Он имеет два новых свойства, для одного из которых реализован обработчик сигнала:
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
} Допустимые типы в пользовательских определениях свойств
В качестве типов пользовательских свойств можно использовать любые основные типы QML, кроме типа перечисления. Например, все следующие являются допустимыми объявлениями свойств:
Item {
property int someNumber
property string someString
property url someUrl
} (Значения перечисления — это просто целые числа, и вместо них можно использовать тип int).
Некоторые основные типы предоставляются модулем QtQuick и поэтому не могут использоваться в качестве типов свойств, если модуль не импортирован. Дополнительные сведения см. в документации по основным типам QML.
Обратите внимание, что базовый тип var — это универсальный тип-заполнитель, который может содержать любые типы значений, включая списки и объекты:
property var someNumber: 1.5
property var someString: "abc"
property var someBool: true
property var someList: [1, 2, "three", "four"]
property var someObject: Rectangle { width: 100; height: 100; color: "red" } Кроме того, в качестве типа свойства можно использовать любой тип QML-объекта. Например:
property Item someItem property Rectangle someRectangle
Это относится и к пользовательским типам QML. Если тип QML был определён в файле с именем ColorfulButton.qml (в каталоге, который затем был импортирован клиентом), то свойство типа ColorfulButton также будет допустимым.
Назначение значений атрибутам свойств
Значение свойства экземпляра объекта можно указать двумя способами:
- присваивание значения при инициализации
- императивное присваивание значения
В обоих случаях значение может быть либо статическим, либо выражением привязки.
Присваивание значения при инициализации
Синтаксис присваивания значения свойству при инициализации:
<propertyName> : <value>
При необходимости присвоение значения при инициализации можно комбинировать с определением свойства в объявлении объекта. В этом случае синтаксис определения свойства становится:
[default] property <propertyType> <propertyName> : <value>
Пример инициализации значения свойства:
import QtQuick 2.0
Rectangle {
color: "red"
property color nextColor: "blue" // combined property declaration and initialization
} Императивное присваивание значения
Императивное присваивание значения — это присваивание значения свойства (либо статического значения, либо выражения привязки) из императивного кода JavaScript. Синтаксис императивного присваивания значения — это просто оператор присваивания JavaScript, как показано ниже:
[<objectId>.]<propertyName> = value
Пример императивного присваивания значения:
import QtQuick 2.0
Rectangle {
id: rect
Component.onCompleted: {
rect.color = "red"
}
} Статические значения и значения выражений привязки
Как уже отмечалось, к свойству можно присвоить два типа значений: статические значения и значения выражений привязки. Последние также известны как привязки свойств.
| Тип | Семантика |
|---|---|
| Статическое значение | Постоянное значение, которое не зависит от других свойств. |
| Выражение привязки | Выражение JavaScript, описывающее взаимосвязь свойства с другими свойствами. Переменные в этом выражении называются зависимостями свойства. Двигатель QML обеспечивает взаимосвязь между свойством и его зависимостями. При изменении значений зависимостей движок QML автоматически пересчитывает выражение привязки и присваивает новое результат свойству. |
Ниже приведен пример, демонстрирующий присвоение обоих типов значений свойствам:
import QtQuick 2.0
Rectangle {
// both of these are static value assignments on initialization
width: 400
height: 200
Rectangle {
// both of these are binding expression value assignments on initialization
width: parent.width / 2
height: parent.height
}
} Примечание: Чтобы императивно присвоить выражение привязки, это выражение должно быть заключено в функцию, которая передаётся в Qt.binding(), а затем возвращаемое значение Qt.binding() должно быть присвоено свойству. В отличие от этого, Qt.binding() не используется при присвоении выражения привязки при инициализации. Дополнительную информацию см. в разделе Привязка свойств.
Безопасность типов
Свойства безопасны с точки зрения типов. Свойству можно присвоить только значение, соответствующее его типу.
Например, если свойство — это вещественное число, и вы попытаетесь присвоить ему строку, получите ошибку:
property int volume: "four" // generates an error; the property's object will not be loaded
Аналогично, если свойству во время выполнения присваивается значение неправильного типа, новое значение не будет присвоено, и будет сгенерирована ошибка.
Некоторые типы свойств не имеют естественного представления значения, и для таких типов свойств движок QML автоматически выполняет преобразование строки в значение соответствующего типа. Поэтому, например, даже если свойства типа color хранят цвета, а не строки, вы можете присвоить строку "red" свойству цвета без появления ошибки.
Список поддерживаемых по умолчанию типов свойств см. в разделе основных типов QML. Кроме того, в качестве типа свойства также можно использовать любой доступный тип QML-объекта.
Специальные типы свойств
Атрибуты свойств типа списка объектов
Свойству типа список можно присвоить список значений типа QML-объекта. Синтаксис для определения значения списка объектов — это список значений, разделённых запятыми, заключённый в квадратные скобки:
[ <item 1>, <item 2>, ... ]
Например, тип Item имеет свойство states, используемое для хранения списка объектов типа State. В приведенном ниже коде значение этого свойства инициализировано списком из трёх объектов State:
import QtQuick 2.0
Item {
states: [
State { name: "loading" },
State { name: "running" },
State { name: "stopped" }
]
} Если список содержит один элемент, квадратные скобки можно опустить:
import QtQuick 2.0
Item {
states: State { name: "running" }
} Свойство типа список можно указать в объявлении объекта следующим образом:
[default] property list<<objectType>> propertyName
и, как и другие объявления свойств, инициализация свойства может быть объединена с объявлением свойства следующим образом:
[default] property list<<objectType>> propertyName: <value>
Пример объявления свойства типа список:
import QtQuick 2.0
Rectangle {
// declaration without initialization
property list<Rectangle> siblingRects
// declaration with initialization
property list<Rectangle> childRects: [
Rectangle { color: "red" },
Rectangle { color: "blue"}
]
} Если вы хотите объявить свойство для хранения списка значений, которые не обязательно являются значениями типа QML-объекта, следует вместо этого объявить свойство типа var.
Сгруппированные свойства
В некоторых случаях свойства содержат логическую группу атрибутов подсвойств. Эти атрибуты подсвойств могут быть назначены с использованием либо обозначения точкой, либо обозначения группы.
Например, тип Text имеет групповое свойство font. Ниже первый объект Text инициализирует свои font значения с использованием обозначения точкой, а второй — с использованием обозначения группы:
Text {
//dot notation
font.pixelSize: 12
font.b: true
}
Text {
//group notation
font { pixelSize: 12; b: true }
} Групповые типы свойств — это базовые типы, которые имеют подсвойства. Некоторые из этих базовых типов предоставляются языком QML, а другие могут использоваться только при импорте модуля Qt Quick. Дополнительную информацию см. в документации о базовых типах QML.
Псевдонимы свойств
Псевдонимы свойств — это свойства, которые содержат ссылку на другое свойство. В отличие от обычного определения свойства, которое выделяет новое, уникальное хранилище для свойства, псевдоним свойства связывает вновь объявленное свойство (называемое псевдонимом свойства) как прямую ссылку на существующее свойство (свойство-оригинал).
Декларация псевдонима свойства похожа на обычное определение свойства, за исключением того, что она требует ключевого слова alias, а не типа свойства, и правая часть объявления свойства должна быть допустимой ссылкой на псевдоним:
[default] property alias <name>: <alias reference>
В отличие от обычного свойства, псевдоним имеет следующие ограничения:
- Он может ссылаться только на объект или свойство объекта, которое находится в области видимости типа типа, в котором объявлен псевдоним.
- Он не может содержать произвольные выражения JavaScript.
- Он не может ссылаться на объекты, объявленные за пределами области видимости своего типа.
- Ссылка на псевдоним не является необязательной, в отличие от необязательного значения по умолчанию для обычного свойства; ссылка на псевдоним должна быть предоставлена при первом объявлении псевдонима.
- Он не может ссылаться на присоединённые свойства.
- Он не может ссылаться на свойства внутри иерархии с глубиной 3 или более. Следующий код не будет работать:
property alias color: myItem.myRect.border.color Item { id: myItem property Rectangle myRect }Однако псевдонимы для свойств, которые имеют глубину до двух уровней, будут работать.
property alias color: rectangle.border.color Rectangle { id: rectangle }
Например, ниже приведён тип Button с алиасом buttonText свойства, который подключён к объекту text дочернего объекта Text:
// Button.qml
import QtQuick 2.0
Rectangle {
property alias buttonText: textItem.text
width: 100; height: 30; color: "yellow"
Text { id: textItem }
} Следующий код создаст Button с определённой строкой текста для дочернего объекта Text:
Button { buttonText: "Click Me" } Здесь изменение buttonText напрямую изменяет значение textItem.text; оно не изменяет какое-либо другое значение, которое затем обновляет textItem.text. Если buttonText не был псевдонимом, изменение его значения фактически не изменило бы отображаемый текст, так как привязки свойств не являются двунаправленными: значение buttonText изменилось бы, если бы изменилось значение textItem.text, но не наоборот.
Учитываемые моменты при использовании псевдонимов свойств
Псевдонимы активируются только после того, как компонент был полностью инициализирован. При попытке обратиться к неинициализированному псевдониму генерируется ошибка. Аналогично, создание псевдонима псевдонима свойства также приведёт к ошибке.
property alias widgetLabel: label //will generate an error //widgetLabel.text: "Initial text" //will generate an error //property alias widgetLabelText: widgetLabel.text Component.onCompleted: widgetLabel.text = "Alias completed Initialization"
Однако при импорте типа QML объекта с псевдонимом свойства в корневом объекте, свойство отображается как обычное свойство Qt и, следовательно, может использоваться в ссылках на псевдонимы.
Возможно, что свойство-псевдоним может иметь то же имя, что и существующее свойство, эффективно перезаписывая существующее свойство. Например, следующий тип QML имеет псевдоним color свойства, который имеет то же имя, что и встроенное свойство Rectangle::color:
Rectangle {
id: coloredrectangle
property alias color: bluerectangle.color
color: "red"
Rectangle {
id: bluerectangle
color: "#1234ff"
}
Component.onCompleted: {
console.log (coloredrectangle.color) //prints "#1234ff"
setInternalColor()
console.log (coloredrectangle.color) //prints "#111111"
coloredrectangle.color = "#884646"
console.log (coloredrectangle.color) //prints #884646
}
//internal function that has access to internal properties
function setInternalColor() {
color = "#111111"
}
} Любой объект, использующий этот тип и ссылающийся на свойство color, будет ссылаться на псевдоним, а не на обычное свойство Rectangle::color. Однако внутренне прямоугольник может правильно установить свойство color и обратиться к фактически определённому свойству, а не к псевдониму.
Псевдонимы свойств и типы
Псевдонимы свойств не могут иметь явных указаний типа. Тип псевдонима свойства — это объявленный тип свойства или объекта, на который он ссылается. Поэтому, если вы создаёте псевдоним для объекта, на который ссылаются по id с дополнительными свойствами, объявленными в строке, то дополнительные свойства не будут доступны через псевдоним:
// MyItem.qml
Item {
property alias inner: innerItem
Item {
id: innerItem
property int extraProperty
}
} Вы не можете инициализировать inner.extraProperty извне этого компонента, так как inner — это только Item:
// main.qml
MyItem {
inner.extraProperty: 5 // fails
} Однако, если вы извлечёте объект inner в отдельный компонент с отдельным файлом .qml, вы можете вместо этого создать экземпляр этого компонента и иметь все его свойства доступными через псевдоним:
// MainItem.qml
Item {
// Now you can access inner.extraProperty, as inner is now an ExtraItem
property alias inner: innerItem
ExtraItem {
id: innerItem
}
}
// ExtraItem.qml
Item {
property int extraProperty
} Свойства по умолчанию
Определение объекта может иметь одно свойство по умолчанию. Свойство по умолчанию — это свойство, которому назначается значение, если объект объявлен внутри определения другого объекта без объявления его в качестве значения для определённого свойства.
Объявление свойства с необязательным ключевым словом default помечает его как свойство по умолчанию. Например, предположим, что есть файл MyLabel.qml со свойством по умолчанию someText:
// MyLabel.qml
import QtQuick 2.0
Text {
default property var someText
text: "Hello, " + someText.text
} Значение someText можно назначить в определении объекта MyLabel следующим образом:
MyLabel {
Text { text: "world!" }
} Это имеет точно такой же эффект, как и следующее:
MyLabel {
someText: Text { text: "world!" }
} Однако, так как свойство someText помечено как свойство по умолчанию, нет необходимости явно назначать объект Text этому свойству.
Вы заметите, что дочерние объекты могут быть добавлены к любому типу, основанному на Item, без явного добавления их в свойство children. Это связано с тем, что свойством по умолчанию для Item является свойство data, и все элементы, добавленные в этот список для Item, автоматически добавляются в его список children.
Свойства по умолчанию могут быть полезны для переназначения дочерних элементов элемента. См. Пример TabWidget, который использует свойство по умолчанию для автоматической переназначения дочерних элементов TabWidget в качестве дочерних элементов внутреннего ListView. См. также Расширение QML.
Только для чтения свойства
Объявление объекта может определять свойство только для чтения, используя ключевое слово readonly, с использованием следующего синтаксиса:
readonly property <propertyType> <propertyName> : <initialValue>
Свойствам только для чтения необходимо назначить значение при инициализации. После инициализации свойства только для чтения его больше нельзя изменить, ни с помощью императивного кода, ни другими способами.
Например, код в блоке Component.onCompleted ниже неверный:
Item {
readonly property int someNumber: 10
Component.onCompleted: someNumber = 20 // doesn't work, causes an error
} Примечание: свойство только для чтения также не может быть свойством по умолчанию по умолчанию.
Объекты-модификаторы свойств
Свойства могут иметь объекты-модификаторы значений свойств, связанные с ними. Синтаксис для объявления экземпляра типа объекта-модификатора свойства, связанного с конкретным свойством, следующий:
<PropertyModifierTypeName> on <propertyName> {
// attributes of the object instance
} Важно отметить, что указанный выше синтаксис фактически является объявлением объекта, который создаст объект, воздействующий на уже существующее свойство.
Определённые типы модификаторов свойств могут быть применимы только к определённым типам свойств, но это не навязывается языком. Например, тип NumberAnimation, предоставляемый QtQuick, будет анимировать только свойства числовых типов (например, int или real). Попытка использовать NumberAnimation с нечисловым свойством не приведёт к ошибке, но нечисловое свойство не будет анимировано. Поведение типа модификатора свойства при связи с конкретным типом свойства определяется его реализацией.
Атрибуты сигнала
Сигнал — это уведомление от объекта о том, что произошло какое-либо событие: например, свойство изменилось, анимация началась или остановилась, или изображение было загружено. Тип MouseArea, например, имеет сигнал clicked, который излучается при нажатии пользователем в области мыши.
Объект может быть уведомлён через обработчик сигнала всякий раз, когда излучается конкретный сигнал. Обработчик сигнала объявляется с синтаксисом on<Signal>, где <Signal> — имя сигнала с прописной первой буквой. Обработчик сигнала должен быть объявлен в определении объекта, который излучает сигнал, и обработчик должен содержать блок кода JavaScript, который будет выполняться при вызове обработчика сигнала.
Например, обработчик сигнала onClicked ниже объявлен внутри объекта MouseArea и вызывается при нажатии на MouseArea, вызывая вывод сообщения в консоль:
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
} Определение атрибутов сигнала
Сигнал может быть определён для типа в C++ путём регистрации Q_SIGNAL класса, который затем регистрируется в системе типов QML. В качестве альтернативы, пользовательский сигнал для типа объекта может быть определён в объявлении объекта в документе QML с использованием следующего синтаксиса:
signal <signalName>[([<type> <parameter name>[, ...]])]
Попытка объявить два сигнала или метода с одинаковым именем в одном блоке типа является ошибкой. Однако новый сигнал может повторно использовать имя существующего сигнала в типе. (Это следует делать осторожно, так как существующий сигнал может быть скрыт и стать недоступным.)
Вот три примера объявлений сигналов:
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
} Если у сигнала нет параметров, квадратные скобки «()» необязательны. Если используются параметры, типы параметров должны быть объявлены, как для аргументов string и var для сигнала actionPerformed выше. Разрешенные типы параметров совпадают с теми, которые перечислены в разделе Определение атрибутов свойства на этой странице.
Для излучения сигнала вызовите его как метод. Все соответствующие обработчики сигналов будут вызваны при излучении сигнала, и обработчики могут использовать определённые имена аргументов сигнала для доступа к соответствующим аргументам.
Сигналы изменения свойства
Типы QML также предоставляют встроенные сигналы изменения свойств, которые излучаются всякий раз, когда значение свойства изменяется, как это было описано ранее в разделе о атрибутах свойств. См. предстоящий раздел о обработчиках сигналов изменения свойства для получения дополнительной информации о том, почему эти сигналы полезны и как их использовать.
Атрибуты обработчиков сигналов
Обработчики сигналов — это особый вид атрибута метода, где реализация метода вызывается движком QML всякий раз, когда излучается связанный сигнал. Добавление сигнала в определение объекта в QML автоматически добавит связанный обработчик сигнала в определение объекта, который по умолчанию имеет пустую реализацию. Клиенты могут предоставить реализацию для реализации логики программы.
Рассмотрим следующий SquareButton тип, определение которого приведено в файле SquareButton.qml в виде показанного ниже, с сигналами activated и deactivated:
// SquareButton.qml
Rectangle {
id: root
signal activated(real xPosition, real yPosition)
signal deactivated
property int side: 100
width: side; height: side
MouseArea {
anchors.fill: parent
onPressed: root.activated(mouse.x, mouse.y)
onReleased: root.deactivated()
}
} Эти сигналы могут быть получены любыми SquareButton объектами в другом файле QML в той же директории, где реализации обработчиков сигналов предоставляются клиентом:
// myapplication.qml
SquareButton {
onActivated: console.log("Activated at " + xPosition + "," + yPosition)
onDeactivated: console.log("Deactivated!")
} См. раздел Система сигналов и обработчиков событий для получения более подробной информации об использовании сигналов.
Обработчики сигналов изменения свойства
Обработчики сигналов для сигнала изменения свойства имеют синтаксическую форму on<Свойство>Changed, где <Свойство> — это имя свойства, первая буква которого заглавная. Например, хотя в документации типа TextInput не документирован сигнал textChanged, этот сигнал неявно доступен благодаря тому, что у TextInput есть свойство text, и поэтому можно написать обработчик сигнала onTextChanged, который будет вызываться всякий раз, когда это свойство изменяется:
import QtQuick 2.0
TextInput {
text: "Change this!"
onTextChanged: console.log("Text has changed to:", text)
} Атрибуты метода
Метод типа объекта — это функция, которую можно вызвать для выполнения некоторой обработки или запуска дополнительных событий. Метод можно подключить к сигналу, чтобы он автоматически вызывался всякий раз, когда излучается сигнал. См. Системы сигналов и обработчиков событий для получения более подробной информации.
Определение атрибутов метода
Метод может быть определен для типа в C++ путём маркирования функции класса, которая затем регистрируется в системе типов QML с помощью Q_INVOKABLE или путём регистрации её как Q_SLOT класса. В качестве альтернативы, пользовательский метод может быть добавлен к объявлению объекта в документе QML с помощью следующего синтаксиса:
function <functionName>([<parameterName>[, ...]]) { <body> } Методы могут быть добавлены к типу QML для определения автономных, повторно используемых блоков кода JavaScript. Эти методы могут вызываться как внутренне, так и внешними объектами.
В отличие от сигналов, типы параметров методов не должны объявляться, так как они по умолчанию имеют тип var.
Попытка объявить два метода или сигнала с одинаковым именем в одном блоке типа — ошибка. Однако новый метод может повторно использовать имя существующего метода типа. (Это следует делать с осторожностью, так как существующий метод может быть скрыт и станет недоступным.)
Ниже приведён Прямоугольник с методом calculateHeight(), который вызывается при назначении значения height:
import QtQuick 2.0
Rectangle {
id: rect
function calculateHeight() {
return rect.width / 2;
}
width: 100
height: calculateHeight()
} Если метод имеет параметры, они доступны по имени внутри метода. Ниже, когда на область мыши нажимают, вызывается метод moveTo(), который может затем использовать полученные параметры newX и newY для изменения позиции текста:
import QtQuick 2.0
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: label.moveTo(mouse.x, mouse.y)
}
Text {
id: label
function moveTo(newX, newY) {
label.x = newX;
label.y = newY;
}
text: "Move me!"
}
} Присоединённые свойства и присоединённые обработчики сигналов
Присоединённые свойства и присоединённые обработчики сигналов — это механизмы, которые позволяют аннотировать объекты дополнительными свойствами или обработчиками сигналов, которые в противном случае недоступны для объекта. В частности, они позволяют объектам получать доступ к свойствам или сигналам, которые имеют отношение к конкретному объекту.
Реализация типа QML может выбрать создание типа присоединения в C++ с определёнными свойствами и сигналами. Экземпляры этого типа могут затем создаваться и присоединяться к определённым объектам во время выполнения, позволяя этим объектам получать доступ к свойствам и сигналам типа присоединения. К ним обращаются, добавляя префикс к свойствам и соответствующим обработчикам сигналов имя типа присоединения.
Ссылки на присоединённые свойства и обработчики имеют следующий синтаксический вид:
<AttachingType>.<propertyName> <AttachingType>.on<SignalName>
Например, тип ListView имеет присоединённое свойство ListView.isCurrentItem, которое доступно каждому объекту-делегата в ListView. Это можно использовать каждому отдельному объекту-делегату для определения, является ли он текущим выбранным элементом в представлении:
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
} В этом случае имя типа присоединения — ListView, а интересующее свойство — isCurrentItem, следовательно, к присоединённому свойству обращаются как к ListView.isCurrentItem.
К присоединённому обработчику сигнала обращаются аналогично. Например, присоединённый обработчик сигнала Component.onCompleted часто используется для выполнения некоторого кода JavaScript, когда процесс создания компонента завершён. В приведённом ниже примере, как только ListModel будет полностью создан, его обработчик сигнала Component.onCompleted будет автоматически вызван для заполнения модели:
import QtQuick 2.0
ListView {
width: 240; height: 320
model: ListModel {
id: listModel
Component.onCompleted: {
for (var i = 0; i < 10; i++)
listModel.append({"Name": "Item " + i})
}
}
delegate: Text { text: index }
} Поскольку имя типа присоединения — Component, и этот тип имеет сигнал completed, к присоединённому обработчику сигнала обращаются как к Component.onCompleted.
Примечание об обращении к присоединённым свойствам и обработчикам сигналов
Распространённой ошибкой является предположение, что к присоединённым свойствам и обработчикам сигналов можно напрямую обратиться из дочерних элементов объекта, к которому эти атрибуты были присоединены. Это не так. Экземпляр типа присоединения присоединяется только к определённым объектам, а не к объекту и всем его дочерним элементам.
Например, ниже приведена изменённая версия предыдущего примера, связанного с присоединёнными свойствами. На этот раз делегат — элемент, а цветной прямоугольник — дочерний элемент этого элемента:
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Item {
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow" // WRONG! This won't work.
}
}
} Это не работает как ожидается, потому что ListView.isCurrentItem присоединён только к корневому объекту-делегату, а не к его дочерним элементам. Поскольку прямоугольник является дочерним элементом делегата, а не самим делегатом, он не может получить доступ к присоединённому свойству isCurrentItem как ListView.isCurrentItem. Вместо этого, прямоугольник должен получить доступ к isCurrentItem через корневой делегат:
ListView {
//....
delegate: Item {
id: delegateItem
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // correct
}
}
} Теперь delegateItem.ListView.isCurrentItem правильно ссылается на присоединённое свойство isCurrentItem делегата.
Атрибуты перечисления
Перечисления предоставляют фиксированный набор именованных вариантов. Их можно объявить в QML, используя ключевое слово enum:
// MyText.qml
Text {
enum TextType {
Normal,
Heading
}
} Как показано выше, типы перечисления (например, TextType) и значения (например, Normal) должны начинаться с заглавной буквы.
К значениям обращаются с помощью <Type>.<EnumerationType>.<Value> или <Type>.<Value>.
// MyText.qml
Text {
enum TextType {
Normal,
Heading
}
property int textType: MyText.TextType.Normal
font.bold: textType == MyText.TextType.Heading
font.pixelSize: textType == MyText.TextType.Heading ? 24 : 12
} Дополнительную информацию об использовании перечислений в QML можно найти в документации основных типов QML перечисление.
Возможность объявлять перечисления в QML появилась в Qt 5.10.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/qtqml-syntax-objectattributes.html