qtbindingqml

How to do a multi-line Qt.binding()


I have a simple QML application where there is a Board (which is just a Rectangle named parentRect) and a smaller child rectangle inside of it (named childRect).

I want to make it so whenever the parentRect's opacity goes from 0 to 1.0, the opacity of childRect also changes the same amount for its final value, but I want the childRect to use an OpacityAnimator performs the animation of the opacity changing.

Here's the catch:

I'm trying to make it so that if the opacity is going from 0 to 1, the OpacityAnimator's duration will be long, and if the opacity is going from 1.0 to 0, the duration will be very short.

So far, here is what I've tried:

Rectangle {
    id: parentRect
    
    Rectangle {
        id: childRect
        opacity: parentRect.opacity
        visible: true
        property int index: 10

        Behavior on opacity {
            OpacityAnimator {
                duration: Qt.binding(function () {
                    if (parentRect.opacity === 0) {
                        return (50 * (index + 2))
                    } else {
                        return (2 * (index + 2))
                    }
                })
            }
        }
    }
}

After executing the code, I get the following error:

qrc:/main.qml:138:47: Invalid use of Qt.binding() in a binding declaration.

Why is my Qt.binding property invalid?


Solution

  • You only use Qt.binding() when making an imperative binding, that is when you do someProp = Qt.binding(someFoo), which unlike a regular assignment will bind the property value to an expression.

    In your case you need to use the regular declarative binding syntax. If it is too complex for a single line, it can be written as a function, save for the "header" part.

    someProp: {
      if (cond) {
         return val1
      } else {
         return val2
      }
    }
    

    If you so chose. Since in your case you could simply use the ternary conditional operator:

    duration: parentRect.opacity ? (50 * (index + 2)) : (2 * (index + 2))
    

    Or even:

    duration: (index + 2) * (parentRect.opacity ? 50 : 2)