How to resolve this loop call caused by property changed in qml, can I stop binding somewhere?

35 views Asked by At
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    property int anum: 0
    property int bnum: 1

    onAnumChanged: {
        bnum+=1
    }

    onBnumChanged: {
        anum+=1
        //Is there some way to stop loop call ?
        //in widget we can unconnect some signal and slot
        //but how to disconnect in qml
    }

    Button{
        text:"begain"
        onClicked: {
            anum=anum+1
        }
    }

}
  1. when i push the button
  2. the 'anum' change to 1
  3. then the function onAnumChanged begain to execute
  4. then the bnum has been changed
  5. then the onBnumChanged begain to execute
  6. then the anum has been changed
  7. then loop from 3 to 7

is there some way to stop this?can i use some unbinding function to stop this like 'disconnect(sender,signal,receiver,slot)' in c++(widget)

1

There are 1 answers

0
Stephen Quan On BEST ANSWER

Several things are needed to help break the binding loop:

  1. Check a break flag as smr has suggested
  2. Allow events, use Qt.callLater() means idle time is granted so events can fire
  3. Define events that reset and set the break flag

We can borrow the userbreak pattern and implement here with mouse tapped, keypress and even visibility changing as things that will raise a userbreak.

import QtQuick
import QtQuick.Controls
Page {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    property int anum: 0
    property int bnum: 1
    property bool userbreak: false

    onAnumChanged: {
        if (userbreak) return;
        Qt.callLater( () => { bnum++ } );
    }

    onBnumChanged: {
        if (userbreak) return;
        Qt.callLater( () => { anum++ } );
        //Is there some way to stop loop call ?
        //in widget we can unconnect some signal and slot
        //but how to disconnect in qml
    }

    Button{
        text: "begain %1 %2".arg(anum).arg(bnum)
        onClicked: {
            userbreak = false;
            Qt.callLater( () => { anum++ } );
        }
    }

    TapHandler {
        onTapped: userbreak = true;
    }

    Keys.onPressed: {
        userbreak = true;
    }

    onVisibleChanged: {
        userbreak = true;
    }
}

You can Try it Online!