QML条件绑定不按预期工作

时间:2015-02-18 09:25:44

标签: qt qml

如果我有一个简单的Binding形式的对象:

Rectangle {
    height: 400
    width: 500

    property var someObj: null

    Binding on color {
        when:  someObj
        value: someObj.color
    }
}

然后我希望当someObj不是null时,someObj的{​​{1}}属性绑定到此对象的color属性。我实际得到的是运行时错误消息:

color

为什么这不起作用?

执行几乎等效的JavaScript表达式:

TypeError: Cannot read property 'color' of null

按预期工作。

3 个答案:

答案 0 :(得分:1)

我会按以下方式进行:

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,则选择颜色属性的值。

编辑:我已经看到很晚了,这只是mlvljr在评论中建议的内容,抱歉。

答案 1 :(得分:0)

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
    }
}

答案 2 :(得分:0)

in the comment by BaCaRoZzo所述,问题中给出的最小示例不起作用,因为它给出了ReferenceError: someObj is not defined。但是,在使用id的{​​{1}}修复此问题之后,尽管TypeError ,该示例实际上仍然有效:

Rectangle

这可以正确设置设置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时已经被求值(请参见QTBUG-22005)。 因此,为了防止Binding,只需检查TypeError的{​​{1}}表达式中要设置的rect.someObj

value