Связывание свойств
Свойству объекта можно присвоить статическое значение, которое остается постоянным до тех пор, пока ему явно не будет присвоено новое значение. Однако, чтобы в полной мере использовать QML и его встроенную поддержку динамического поведения объектов, большинство объектов QML используют связывание свойств.
Связывание свойств — это ключевая функция QML, которая позволяет разработчикам задавать взаимосвязи между различными свойствами объектов. Когда зависимости свойства изменяются, свойство автоматически обновляется в соответствии с заданной взаимосвязью.
Внутри QML движок отслеживает зависимости свойства (то есть переменные в выражении связывания). При обнаружении изменения QML движок повторно оценивает выражение связывания и применяет новый результат к свойству.
Обзор
Для создания связывания свойства свойству присваивается выражение JavaScript, которое вычисляется до желаемого значения. В простейшем случае связывание может быть ссылкой на другое свойство. Рассмотрим следующий пример, где высота синего прямоугольника связана с высотой его родителя:
Rectangle {
width: 200; height: 200
Rectangle {
width: 100
height: parent.height
color: "blue"
}
} Всякий раз, когда высота родительского прямоугольника изменяется, высота синего прямоугольника автоматически обновляется до того же значения.
Связывание может содержать любое допустимое выражение или оператор JavaScript, так как QML использует стандартный движок JavaScript. Связывания могут обращаться к свойствам объектов, вызывать методы и использовать встроенные объекты JavaScript, такие как Date и Math. Ниже приведены другие возможные связывания для предыдущего примера:
height: parent.height / 2
height: Math.min(parent.width, parent.height)
height: parent.height > 100 ? parent.height : parent.height/2
height: {
if (parent.height > 100)
return parent.height
else
return parent.height / 2
}
height: someMethodThatReturnsHeight() Ниже приведен более сложный пример, включающий больше объектов и типов:
Column {
id: column
width: 200
height: 200
Rectangle {
id: topRect
width: Math.max(bottomRect.width, parent.width/2)
height: (parent.height / 3) + 10
color: "yellow"
TextInput {
id: myTextInput
text: "Hello QML!"
}
}
Rectangle {
id: bottomRect
width: 100
height: 50
color: myTextInput.text.length <= 10 ? "red" : "blue"
}
} В предыдущем примере,
-
topRect.widthзависит отbottomRect.widthиcolumn.width -
topRect.heightзависит отcolumn.height -
bottomRect.colorзависит отmyTextInput.text.length
Синтаксически связывания могут иметь произвольную сложность. Однако, если связывание слишком сложное — например, включает несколько строк или императивные циклы — это может указывать на то, что связывание используется для чего-то большего, чем описание взаимосвязей свойств. Сложные связывания могут снизить производительность кода, читаемость и сопровождаемость. Возможно, стоит перепроектировать компоненты со сложными связываниями или хотя бы вынести связывание в отдельную функцию.
Создание связываний свойств из JavaScript
Свойство со связыванием автоматически обновляется по мере необходимости. Однако, если свойству позже будет присвоено статическое значение из оператора JavaScript, связывание будет удалено.
Например, в прямоугольнике ниже изначально гарантируется, что его height всегда в два раза больше его width. Однако, когда нажимается клавиша пробела, текущее значение width*3 будет присвоено height как статическое значение. После этого height будет оставаться фиксированным на этом значении, даже если width изменится. Присвоение статического значения удаляет связывание.
import QtQuick 2.0
Rectangle {
width: 100
height: width * 2
focus: true
Keys.onSpacePressed: {
height = width * 3
}
} Если цель заключается в присвоении прямоугольнику фиксированной высоты и остановке автоматических обновлений, то это не проблема. Однако, если цель заключается в установлении новой взаимосвязи между width и height, то новое выражение связывания необходимо заключить в функцию Qt.binding():
import QtQuick 2.0
Rectangle {
width: 100
height: width * 2
focus: true
Keys.onSpacePressed: {
height = Qt.binding(function() { return width * 3 })
}
} Теперь, после нажатия клавиши пробела, высота прямоугольника будет продолжать автоматически обновляться, всегда будучи в три раза больше его ширины.
Использование this со связыванием свойств
При создании связывания свойства из JavaScript можно использовать ключевое слово this, чтобы сослаться на объект, который получает связывание. Это полезно для разрешения неоднозначностей с именами свойств.
Например, обработчик Component.onCompleted ниже определен в области видимости элемента. В этой области видимости width относится к ширине элемента, а не к ширине прямоугольника. Чтобы связать height прямоугольника со своим собственным width, выражение связывания должно явно ссылаться на this.width (или, альтернативно, rect.width):
Item {
width: 500
height: 500
Rectangle {
id: rect
width: 100
color: "yellow"
}
Component.onCompleted: {
rect.height = Qt.binding(function() { return this.width * 2 })
console.log("rect.height = " + rect.height) // prints 200, not 1000
}
} Примечание: Значение this не определено вне связываний свойств. Подробности см. в разделе Ограничения среды JavaScript.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qtqml-syntax-propertybinding.html