简述
可以为 QML 对象中的属性分配两种类型的值 - 静态值和绑定表达式,后者也称为属性绑定。
- 静态值:一个不依赖于其他属性的常数值。
- 绑定表达式:一个用于描述属性间依赖关系的 JavaScript 表达式。
属性绑定是 QML 的一个核心特性,允许指定不同对象属性之间的依赖关系。当属性的依赖项(属性绑定中的变量)的值发生改变时,属性将根据指定的关系自动更新。
- 简述
- 静态值
- 属性绑定
- 使用属性绑定
- 从 JavaScript 创建属性绑定
- 在属性绑定中使用 this
版权所有:一去丶二三里,转载请注明出处:http://blog.csdn.net/liang19890820
静态值
所谓静态值,就是一个不依赖于其他属性的常数值。例如:width : 100
,其中 100 就是一个静态值。
下面的示例,将 Rectangle 的 width 和 height 均分配为静态值。
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
}
// 调用方法
height: someMethodThatReturnsWidth()
在语法上,绑定允许具有任意复杂性(例如:涉及多行或命令循环)。但是,如果绑定过于复杂,可能会降低代码性能、可读性、和可维护性。比较好的方法是:重新设计具有复杂绑定的组件,或者至少将绑定转换为单独的函数。
从 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
}
}
可以看出,this 指向的是接收 Qt.binding() 的返回值的对象。在这里,可以理解为 rect 表示的对象。
注意: this 的值不是在属性绑定之外定义的。