QML 条件绑定未按预期工作
Posted
技术标签:
【中文标题】QML 条件绑定未按预期工作【英文标题】:QML conditional Binding not working as expected 【发布时间】:2015-02-18 09:25:44 【问题描述】:如果我有一个简单的Binding
形式的对象:
Rectangle
height: 400
width: 500
property var someObj: null
Binding on color
when: someObj
value: someObj.color
那么我希望当someObj
不是null
时,someObj
的color
属性绑定到该对象的color
属性。我实际得到的是运行时错误消息:
TypeError: Cannot read property 'color' of null
这不起作用的任何原因?
执行几乎等效的 javascript 表达式:
color:
if ( someObj != null )
return someObj.color;
else
return "black";
按预期工作。
【问题讨论】:
在我看来是个错误。 嗯...您是否尝试减少到最小示例以隔离(可能的)错误?如果您可以发布该最小示例,那么查看它会很有趣。 @BaCaRoZzo 我在问题中编辑了一个最小示例。 @Mitch 已经有一个关于这个的错误报告,也很旧:bugreports.qt.io/browse/QTBUG-22005 这里只是一个简单的color: someObj? someObj.color: "black"
就足够了,顺便说一句(请注意,当您在项目的“内部”您想要哪些属性时,您不需要实例化Binding
对象绑定)
【参考方案1】:
正如in the comment by BaCaRoZzo 所述,问题中给出的最小示例不起作用,因为它给出了ReferenceError: someObj is not defined
。然而,在为Rectangle
使用id
修复此问题后,尽管出现了 TypeError,该示例仍然有效:
Rectangle
id: rect
height: 400
width: 500
property var someObj: null
Binding on color
when: rect.someObj
value: rect.someObj.color
当设置rect.someObj
并包含color
属性时,这会按预期正确设置颜色。
TypeError
的原因是表达式 rect.someObj.color
在创建 Binding
时已被计算(请参阅QTBUG-22005)。
因此,为了防止TypeError
,可以简单地检查rect.someObj
是否设置在Binding
的value
表达式中:
Binding on color
when: rect.someObj
value: rect.someObj ? rect.someObj.color : undefined
【讨论】:
【参考方案2】:我会这样做:
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle
height: 400
width: 500
property var someObj
color: someObj ? someObj.color : "black"
Button
id: buttonTest
text: "test"
onClicked: parent.someObj = test
Button
id: buttonTest2
anchors.left: buttonTest.right
text: "test2"
onClicked: parent.someObj = test2
QtObject
id: test
property color color: "red"
QtObject
id: test2
property color color: "blue"
如果 someObj
未定义,则矩形的颜色为黑色,如果定义了 someObj,则选择 color 属性的值。
编辑:我看到晚了,这只是 mlvljr 在 cmets 中建议的,抱歉。
【讨论】:
【参考方案3】:QML
语法定义属性值初始化赋值右侧的花括号表示绑定赋值。这在初始化 var
属性时可能会造成混淆,因为 JavaScript 中的空花括号可以表示表达式块或空对象声明。 如果您希望将 var
属性初始化为空对象值,则应将花括号括在括号中。
例如:
Item
property var first: // nothing = undefined
property var second: // empty expression block = undefined
property var third: () // empty object
在前面的示例中,第一个属性绑定到一个空表达式,其结果为undefined
。第二个属性绑定到包含单个空表达式块("")
的表达式,该表达式同样具有undefined
结果。第三个属性绑定到一个表达式,该表达式被评估为一个空对象声明,因此该属性将使用该空对象值进行初始化。
同样,JavaScript 中的冒号既可以是对象属性赋值,也可以是代码标签。因此,使用对象声明初始化 var
属性也可能需要括号:
Item
property var first: example: 'true' // example is interpreted as a label
property var second: ( example: 'true' ) // example is interpreted as a property
property var third: 'example': 'true' // example is interpreted as a property
Component.onCompleted:
console.log(first.example) // prints 'undefined', as "first" was assigned a string
console.log(second.example) // prints 'true'
console.log(third.example) // prints 'true'
所以代码应该如下:
Rectangle
height: 400
width: 500
property var someObj: (color: '')
Binding on color
when: someObj.color
value: someObj.color
【讨论】:
以上是关于QML 条件绑定未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章