Important: Please read the Qt Code of Conduct -

Binding loop problem

  • Hi,

    I'm getting a binding loop on a property.
    The property is linked to multiple parameters. Now I get it 8 times when I do a particular action, lets say 'A' the first time. After which performing the same action doesn't result in the same warning.

    The next thing to note is that it only comes if I run the code (that is, while debugging I don't see the warning). This led me to believe that there may be some uninitialized values originally. But I printed all the values (console.log) and they were printed successfully.

    Another thing to note is that I've localized the problem to a recent change (commenting that part removed the warning).

    property int  <last saved value>: 0
    myProperty: {
      if(!<some q_property> && <some other q_property>)
         return <last saved value>
      <last saved value> = <current value from hardware>
      return <current value from hardware>

    Any comments on what I might be doing wrong?

  • Moderators

    Any comments on what I might be doing wrong?

    The problem is that you use and modify <last saved value> in the same JS function. So QML engine will try to evaluate that expression (myProperty value) in a tight loop and think there is a binding loop.

    So what you need to do is to separate these assignments so that myProperty setter does not modify last saved value.

    For example:

    function checkValue() {
    if ((!someQProperty && someOtherQProperty) === false) 
        lastSavedValue = currentValueFromHardware
    property int  lastSavedValue: 0
    onSomeQPropertyChanged: checkValue()
    onSomeOtherQPropertyChanged: checkValue()
    myProperty: lastSavedValue

  • @sierdzio Thanks for the excellent answer.

    The first problem with the advices approach is that the real code has many more "if conditions" for "myProperty".

    The second problem is that qProperty (exposed from Qt) cannot directly be connected via OnQPropertyChanged. I tried using Connection{ target:something onProprtyChanged: {} } that just to verify, got some error "Cannot assign a value directly to a grouped property".

    Thirdly, the implementation is inside another object (defined in the form class). For some reason (I'm still new to QML), I can't access property defined in the qml file outside of the object, and I can't create a function inside of it.

    Overall even if all of that did work, I'm basically writing too much code for the little impact. It would cause too much confusion. From your explaination, this isn't a binding loop, QML just evaluates it as one. Can't I suppress the warning in this case somehow?

  • Moderators

    @Ankit.Jain said in Binding loop problem:

    From your explaination, this isn't a binding loop, QML just evaluates it as one. Can't I suppress the warning in this case somehow?

    It is a binding loop, and QML engine will disable the code after it is detected. You have to rewrite this if you want this code to work.

    QML is declarative, which means each time you change any of the properties used to calculate value of myProperty, the whole expression is evaluated again. And in your case, when you change last saved value, expression is reevaluated and it might change value again, so expression gets evaluated again, and it might update thwe value... and so on, ad infinitum.

    If rewriting the code in a way I proposed is too complex in your case, think of a different solution. I'm sure mine is not the only one.

  • @sierdzio Thanks again.
    I think I finally see why it's a binding loop now. To be honest, my code is still working, its just throwing this error.
    Guess I'll have to switch my implementation.

Log in to reply