我想创建一个具有两个属性的自定义 QML 组件one
和two
,它在未初始化时应该具有默认值。特别是,如果two
应该得到一个初始值取决于one
. 以下代码
Rectangle {
property int one: 1
property int two: 2 * one
}
但是会创建一个属性绑定:每当one
更改时,都会将 .two
的新值更新为2 * one
. 如何在不创建绑定的情况下初始化two
为 的值?2 * one
一种明确告诉您不需要绑定的方法是在表达式块中调用赋值:
Rectangle {
property int one: 1
property int two: {two = 2 * one}
}
与在 onCompleted 中打破绑定的方法不同,表达式块避免了绑定对象的创建和销毁,而且看起来更简洁。
在组件完成时显式中断绑定:
Rectangle {
property int one: 1
property int two: 2 * one
Component.onCompleted: two = two
}
two = two
分配会破坏绑定,并且two
不再随着更改而更新one
。
仔细检查是否不需要 Binding 并注意不要使代码变脏。
您可以按如下方式尽快用值填充属性:
window {
id: win
width: 300; height: 450
color: "#d8d8d8"
Item {
property int val1
property int val2
property int val3: parent.width //<-- Binding
Component.onCompleted: {
val1 = win.width; //<---|
val2 = win.height; //<---|=== There is no binding. Just changes value
/* ... */
}
}
}
(我不确定,您也许可以使用Component.onStatusChanged
和Component.Ready
状态设置初始值)
性能注意事项:信号和 Javascript 代码对性能有一些影响。使用绑定可能会更高效。使用 Profiler 进行检查。如果你想设置多个属性的初始值或者你已经使用了onCompleted
信号,那么这将提高性能!
事实上,你不应该这样做。绑定是 QML 的基本行为,如果你试图避免它,那是因为你没有考虑好的方法。
例如,如果属性二的初始值是用属性一的初始值而不是属性一的值计算的,
那么这意味着您要绑定Initial value而不是value,您应该创建一个只读属性,该属性的值将是属性一个初始值:
readonly property int initialOne : 1;
property int one : initialOne;
property int two : 2 * initialOne;
它可能看起来有点沉重,但如果你仔细想想,初始值就是你想要使用的,所以,属性的概念就是你真正想要的