Атрибуты 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] [required] [readonly] property <propertyType> <propertyName>
Таким образом, объявление объекта может предоставить определённое значение внешним объектам или более удобно поддерживать внутреннее состояние.
Имена свойств должны начинаться с маленькой буквы и могут содержать только буквы, цифры и символы нижнего подчеркивания. Зарезервированные слова JavaScript не являются допустимыми именами свойств. Ключевые слова default, required, и readonly необязательны и изменяют семантику объявляемого свойства. Дополнительную информацию см. в следующих разделах: Свойства по умолчанию, Обязательные свойства и Только для чтения свойства.
Объявление пользовательского свойства неявно создаёт сигнал изменения значения для этого свойства, а также связанный обработчик сигналов, называемый 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 можно использовать тип 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>
В отличие от обычного свойства, псевдоним имеет следующие ограничения:
- Он может ссылаться только на объект или свойство объекта, которые находятся в области видимости типа type, в котором объявлен псевдоним.
- Он не может содержать произвольные выражения 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.
Обязательные свойства
Объявление объекта может определить свойство как обязательное, используя ключевое слово required. Синтаксис
required property <propertyType> <propertyName>
Как следует из названия, обязательные свойства должны быть установлены при создании экземпляра объекта. Нарушение этого правила приведёт к тому, что QML-приложения не будут запускаться, если это можно обнаружить статически. В случае динамически созданных QML-компонентов (например, с помощью Qt.createComponent()), нарушение этого правила приводит к предупреждению и возвращаемому значению null.
Возможно сделать существующее свойство обязательным с помощью
required <propertyName>
Следующий пример показывает, как создать пользовательский компонент Rectangle, в котором свойство color всегда необходимо указывать.
// ColorRectangle.qml
Rectangle {
required color
} Примечание: Вы не можете присвоить начальное значение обязательному свойству из QML, так как это противоречит задуманному использованию обязательных свойств.
Обязательные свойства играют особую роль в коде модели-представления-делегата: если делегат представления имеет обязательные свойства, имена которых совпадают с именами ролей модели представления, то эти свойства будут инициализированы соответствующими значениями модели. Для получения дополнительной информации посетите страницу Модели и представления в Qt Quick.
и {QQuickView::setInitialProperties} для способов инициализации обязательных свойств из C++.
Только для чтения свойства
Объявление объекта может определить свойство только для чтения, используя ключевое слово readonly со следующим синтаксисом:
readonly property <propertyType> <propertyName> : <initialValue>
Свойства только для чтения должны быть назначены значение при инициализации. После инициализации свойства только для чтения больше невозможно назначить ему значение, ни из императивного кода, ни иным способом.
Например, код в блоке Component.onCompleted ниже является некорректным:
Item {
readonly property int someNumber: 10
Component.onCompleted: someNumber = 20 // doesn't work, causes an error
} Примечание: Свойство только для чтения не может также быть свойством по умолчанию default.
Объекты-модификаторы свойств
Свойства могут иметь объекты-модификаторы значения свойств, связанные с ними. Синтаксис объявления экземпляра типа модификатора свойства, связанного с конкретным свойством, следующий:
<PropertyModifierTypeName> on <propertyName> {
// attributes of the object instance
} Это обычно называется синтаксисом "on".
Важно отметить, что вышеприведенный синтаксис фактически является объявлением объекта, которое создаст объект, который действует на уже существующее свойство.
Некоторые типы модификаторов свойств могут быть применимы только к определённым типам свойств, однако язык этого не проверяет. Например, тип 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
onReleased: root.deactivated()
onPressed: (mouse)=> root.activated(mouse.x, mouse.y)
}
} Эти сигналы могут быть получены любыми SquareButton объектами в другом файле QML в той же директории, где реализации обработчиков сигналов предоставляются клиентом:
// myapplication.qml
SquareButton {
onDeactivated: console.log("Deactivated!")
onActivated: (xPosition, yPosition)=> console.log("Activated at " + xPosition + "," + yPosition)
} Дополнительные сведения об использовании сигналов см. в разделе Система событий сигналов и обработчиков.
Обработчики сигналов изменения свойства
Обработчики сигналов для сигналов изменения свойства имеют синтаксическую форму on<Свойство>Changed, где <Свойство> — имя свойства, первая буква которого заглавная. Например, хотя документация типа TextInput не документирует сигнал textChanged, этот сигнал неявно доступен благодаря наличию свойства text у TextInput, поэтому можно написать обработчик сигнала 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.
Попытка объявить два метода или сигнала с одинаковым именем в одном блоке типа является ошибкой. Однако новый метод может повторно использовать имя существующего метода в типе. (Это следует делать с осторожностью, так как существующий метод может быть скрыт и станет недоступным.)
Ниже приведен прямоугольник Rectangle с методом calculateHeight(), который вызывается при назначении значения height.
import QtQuick 2.0
Rectangle {
id: rect
function calculateHeight() {
return rect.width / 2;
}
width: 100
height: calculateHeight()
} Если метод имеет параметры, они доступны по имени внутри метода. Ниже, когда происходит щелчок на MouseArea, вызывается метод moveTo(), который может ссылаться на полученные параметры newX и newY для перепозиционирования текста:
import QtQuick 2.0
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: (mouse)=> 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.
Примечание по доступу к присоединённым свойствам и обработчикам сигналов
Частая ошибка заключается в предположении, что присоединённые свойства и обработчики сигналов напрямую доступны из потомков объекта, к которому эти атрибуты были присоединены. Это не так. Экземпляр типа присоединения прикрепляется только к определённым объектам, а не к объекту и всем его потомкам.
Например, ниже приведён модифицированный пример, связанный с присоединёнными свойствами. На этот раз делегатом является Item, а цветной Rectangle — дочерний элемент этого элемента:
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 присоединён только к корневому объекту делегата, а не к его дочерним элементам. Поскольку Rectangle является дочерним элементом делегата, а не самим делегатом, он не может получить доступ к присоединённому свойству 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.
См. также QQmlComponent::createWithInitialProperties и QQmlApplicationEngine::setInitialProperties.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qtqml-syntax-objectattributes.html