簡述
可以為 QML 對象中的屬性配置設定兩種類型的值 - 靜态值和綁定表達式,後者也稱為屬性綁定。
- 靜态值:一個不依賴于其他屬性的常數值。
- 綁定表達式:一個用于描述屬性間依賴關系的 JavaScript 表達式。
屬性綁定是 QML 的一個核心特性,允許指定不同對象屬性之間的依賴關系。當屬性的依賴項(屬性綁定中的變量)的值發生改變時,屬性将根據指定的關系自動更新。
| 版權聲明:一去、二三裡,未經部落客允許不得轉載。
靜态值
所謂靜态值,就是一個不依賴于其他屬性的常數值。例如:
width : 100
,其中 100 就是一個靜态值。
下面的示例,将 Rectangle 的 width 和 height 均配置設定為靜态值。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SO1MzNxYGO5M2NzADO0MTZyYzX1UzNzATM5IzLcdDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.gif)
import QtQuick 2.3
Rectangle {
// 初始化指派 - 靜态值
width: 200
height: 200
Rectangle {
// 初始化指派 - 靜态值
width: 100
height: 100
color: "blue"
既然藍色 Rectangle 的 width 和 height 都是靜态值,那麼當父 Rectangle 大小發生變化時,藍色 Rectangle 的大小必然不會改變。
屬性綁定
屬性綁定,簡單的了解就是一個綁定表達式,用于描述屬性之間的依賴關系。例如:
width : parent.width / 2
。
QML 引擎作為屬性綁定的幕後推手,在時刻監視屬性的依賴項,當檢測到任何依賴項的值發生改變後,就會自動重新計算綁定表達式,并為屬性配置設定新的結果。
使用屬性綁定
要建立一個屬性綁定,需要為屬性配置設定一個 JavaScript 表達式,該表達式将計算所需的值。最簡單的情況,綁定是對另一屬性的引用。
下面的示例,将藍色 Rectangle 的 width 綁定到其 parent 的 width:
import QtQuick 2.3
Rectangle {
width:200
height: 200
Rectangle {
width: parent.width
height: 100
color: "blue"}
}
每當父 Rectangle 的 width 發生變化,藍色 Rectangle 的 width 就會自動更新為相同的值。
綁定可以包含任何有效的 JavaScript 表達式或語句,因為 QML 使用了一個符合标準的 JavaScript 引擎。綁定可以通路對象屬性、調用方法、并使用内置的 JavaScript 對象(例如:Date、Math)。下面是上述示例的其他可能性綁定:
// 通路對象屬性
width: parent.width / 2
// 使用内置的 JavaScript 對象 Math
width: Math.min(parent.width, parent.height)
// 使用三目運算符
width: parent.width > 100 ? parent.width : parent.width /2
// if-else 代碼塊中的 return 關鍵字可有可無
width: {
if (parent.width > 100)
return parent.width
else
return parent.width / 2
}
// 調用方法
在文法上,綁定允許具有任意複雜性(例如:涉及多行或指令循環)。但是,如果綁定過于複雜,可能會降低代碼性能、可讀性、和可維護性。比較好的方法是:重新設計具有複雜綁定的元件,或者至少将綁定轉換為單獨的函數。
從 JavaScript 建立屬性綁定
具有綁定的屬性将根據需要自動更新,但是,如果稍後從 JavaScript 語句為該屬性重新配置設定一個靜态值,則将會移除綁定。
例如,下面的藍色 Rectangle 最初確定其 width 總是其 parent 的 width 的 1/4。但是,當按下空格鍵時,parent.width / 2 将作為靜态值指派給 width。随後,即使其 parent 的 width 發生變化,其 width 也将保持不變,因為靜态值的配置設定移除了綁定。
import QtQuick 2.3
Rectangle {
width: 200
height: 200
Rectangle {
id: rect
width: parent.width / 4
height: 50
color: "blue"
focus: true
Keys.onSpacePressed: {
width = parent.width / 2
如果目的是為了給藍色 Rectangle 一個固定的 width 并停止自動更新,那麼這沒有任何問題。但是,如果是為了給 width 和其 parent 的 width 建立一個新的關系,那麼新的綁定表達式必須被包裹在 Qt.binding() 函數中:
//...
Keys.onSpacePressed: {
width = Qt.binding(function() { parent.width / 2 })
}
//...
現在,按下空格鍵後,矩形的高度将繼續自動更新,始終為其 parent 的 width 的 1/2。
在屬性綁定中使用 this
當從 JavaScript 建立一個屬性綁定時,this 關鍵字可用于引用接收綁定的對象,這有助于解決屬性名稱産生的歧義。
例如,下面的 Component.onCompleted 處理程式在 Item 的範圍内定義。此範圍内,width 是指 Item 的 width,而不是 Rectangle 的 width。要将 Rectangle 的 height 綁定到其自身的 width,綁定表達式必須顯式地引用 this.width(或者 rect.width):
import QtQuick 2.3
Item {
width: 200
height: 200
Rectangle {
id: rect
width: 100
color: "blue"
}
Component.onCompleted: {
rect.height = Qt.binding(function() return this.width * 2 })
console.log("rect.height = " + rect.height) // 列印 200, 而非 400