Spec-Zone.ru › Qt 6.0

Атрибуты 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 Basic Types.

Обратите внимание, что базовый тип 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 Basic Types. Кроме того, в качестве типа свойства также можно использовать любой доступный тип 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 и обратиться к фактически определённому свойству, а не к псевдониму.

Псевдонимы свойств и типы

Псевдонимы свойств не могут иметь явных указаний на тип. Тип псевдонима свойства — это объявленный тип свойства или объекта, на который он ссылается. Следовательно, если вы создаёте псевдоним объекта, на который ссылаются по идентификатору с дополнительными свойствами, объявленными в строке, дополнительные свойства не будут доступны через псевдоним:

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

Примечание: Свойство, доступное только для чтения, не может быть также свойством по умолчанию.

Объекты-модификаторы свойств

Свойства могут иметь объекты-модификаторы значений свойств, связанные с ними. Синтаксис объявления экземпляра типа модификатора свойства, связанного с конкретным свойством, следующий:

<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.

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

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

Spec-Zone.ru

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