Spec-Zone.ru › Qt 5.15

Атрибуты объектов 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.)

Некоторые базовые типы предоставляются модулем 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 с дополнительными объявленными inline свойствами, дополнительные свойства не будут доступны через псевдоним:

// 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
}

Важно отметить, что приведенный выше синтаксис фактически является объявлением объекта object declaration, которое создаст объект, действующий на уже существующее свойство.

Определенные типы модификаторов свойств могут быть применимы только к определенным типам свойств, однако это не контролируется языком. Например, тип 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.

Попытка объявить два метода или сигнала с одинаковым именем в одном блоке типа является ошибкой. Однако новый метод может повторно использовать имя существующего метода на типе. (Это следует делать с осторожностью, так как существующий метод может быть скрыт и стать недоступным.)

Ниже приведен 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: 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-5.15/qtqml-syntax-objectattributes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API