Details
-
Suggestion
-
Status: Reported
-
Not Evaluated
-
Resolution: Unresolved
-
None
-
None
Description
QML prints "Binding loop detected for property XYZ". Having a similar (toggleable?) warning in C++ could help to flag programming errors.
(Demos below ran on Qt 6.4.2)
QML code
import QtQuick import QtQuick.Controls Window { visible: true width: 640 height: 480 property int alpha: 0 property int beta: alpha onAlphaChanged: { if (alpha > 0) { console.log("Going negative") alpha = -1 } console.log(`Alpha = ${alpha} Beta = ${beta}`) } onBetaChanged: { if (alpha < 0) { console.log("Going positive") alpha = 1 // OR: `Qt.callLater(()=>{alpha = 1})` to remove Binding loop complaint } console.log(`Alpha = ${alpha} Beta = ${beta}`) } Button { text: "Click Me" onClicked: alpha = 1 } }
C+ code+
#include <QApplication> #include <QPushButton> #include <QProperty> #include <QDebug> int main(int argc, char *argv[]) { qputenv("QT_LOGGING_RULES", "qt.qproperty.binding=true;"); QApplication app(argc, argv); QProperty<int> alpha{0}; QProperty<int> beta([&]{ return alpha.value(); }); auto alphaHandler = alpha.onValueChanged([&]{ if (alpha > 0) { qDebug("Going negative"); alpha = -1; } qDebug().noquote() << u"Alpha = %1\tBeta = %2"_qs.arg(alpha).arg(beta); }); auto betaHandler = beta.onValueChanged([&]{ if (alpha < 0) { qDebug("Going positive"); alpha = 1; // OR: `QTimer::singleShot(0, &app, [&]{alpha = 1;});` for infinite spam } qDebug().noquote() << u"Alpha = %1\tBeta = %2"_qs.arg(alpha).arg(beta); }); QPushButton button("Click Me"); QObject::connect(&button, &QPushButton::clicked, [&]{ alpha = 1; }); button.show(); return app.exec(); }
QML output when button is clicked
qml: Going negative qml: Alpha = -1 Beta = 0 qml: Going positive qml: Going negative qml: Alpha = -1 Beta = -1 qrc:/main.qml:4:1: QML QQuickWindowQmlImpl*: Binding loop detected for property "beta" qml: Alpha = -1 Beta = -1 qrc:/main.qml:4:1: QML QQuickWindowQmlImpl*: Binding loop detected for property "beta" qml: Alpha = -1 Beta = -1 qml: Alpha = -1 Beta = -1
C+ output when button is clicked+
Going negative Going positive Alpha = 1 Beta = -1 Alpha = 1 Beta = -1
Other observations
- It looks like QProperty and the QML engine don't follow the same sequence when evaluating property bindings – is this intentional?
- Both QProperty and the QML engine do have a mechanism to detect and break binding loops.
Attachments
Issue Links
- relates to
-
QTBUG-110291 C++ equivalent of "qt.qml.binding.removal" logs
-
- Reported
-