Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QML conditional Binding not working as expected

Tags:

qt

qml

If I have a simple Binding object of the form:

Rectangle {
    height: 400
    width: 500

    property var someObj: null

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

Then I would expect that when someObj is not null, someObj's color property is bound to this object's color property. What I actually get is a runtime error message:

TypeError: Cannot read property 'color' of null

Any reason why this doesn't work?

Doing the almost equivalent JavaScript expression:

color: {
    if ( someObj != null ) {
        return someObj.color;
    } else {
        return "black";
    }
}

Works as expected.

like image 433
cmannett85 Avatar asked Feb 18 '15 09:02

cmannett85


2 Answers

As mentioned in the comment by BaCaRoZzo, the minimal example given in the question does not work because it gives a ReferenceError: someObj is not defined. However, after fixing this with an id for the Rectangle, then the example actually works despite the TypeError:

Rectangle {
    id: rect

    height: 400
    width: 500

    property var someObj: null

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

This correctly sets the color as expected when rect.someObj is set and contains a color property.

The reason for the TypeError is that the expression rect.someObj.color is evaluated already when the Binding is created (see QTBUG-22005). So to prevent the TypeError, one can simply check for rect.someObj to be set in the value expression of the Binding:

    Binding on color {
        when:  rect.someObj
        value: rect.someObj ? rect.someObj.color : undefined
    }
like image 117
Ignitor Avatar answered Nov 01 '22 14:11

Ignitor


I would do it in the following way:

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

If someObj is undefined the color of the rectangle is black, if someObj is defined, the Value of the color property is chosen.

Edit: I've seen to late, that that's only what mlvljr suggested in the comments, sorry.

like image 37
Florian Schmidt Avatar answered Nov 01 '22 15:11

Florian Schmidt