1
votes

I'm having a binding loop problem, the code actually works, but I want to get rid of these warnings.

If I return a constant value from the calculateMaxWidth() function, then no warnings, but as soon as I use TextMetrics things get bad. Interestingly, with every new cycle in the for loop I get more and more warnings. If I put the TextMetrics creation inside the for loop along with the destroy, I get a single warning for each measured text.

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: theWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Binding loop! Why?")

    property var mydata: ['somethinglonglikecucumber', 'tomato', 'potato']

    function calculateMaxWidth() {
        var maxWidth = 0;

        var textMetrics = Qt.createQmlObject('import QtQuick 2.12; TextMetrics {} ', theWindow);
        textMetrics.font.pixelSize = 12;

        for(var i=0; i<mydata.length; i++) {
            textMetrics.text = mydata[i];
            console.log("width of " + textMetrics.text + " is " + textMetrics.width)
            maxWidth = Math.max(maxWidth, textMetrics.width);
        }

        textMetrics.destroy();
        return maxWidth;
    }

    Rectangle {
        width: calculateMaxWidth()
        height: 30 * mydata.length
        color: "yellow"
    }
}

And this is the default main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

qrc:/main.qml:29:5: QML Rectangle: Binding loop detected for property "width"

1

1 Answers

1
votes

Assignment to TextMetrics / FontMetrics properties somehow causes the binding loop warnings. However querying FontMetrics' boundingRect won't create the assignment so no warning will appear. Also I had to pass the font size as a property binding during creation of the FontMetrics object.

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: theWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Binding loop solved!")

    property var mydata: ['somethinglonglikecucumber', 'tomato', 'potato']

    function calculateMaxWidth(pixelSize) {
        var maxVal = 0;

        var fontMetrics = Qt.createQmlObject('import QtQuick 2.12; FontMetrics {font.pixelSize:' + pixelSize + '}', theWindow);

        for(var i=0; i<mydata.length; i++) {
            maxVal = Math.max(maxVal, fontMetrics.boundingRect(mydata[i]).width);
        }

        fontMetrics.destroy();

        return maxVal;
    }

    Rectangle {
        width: calculateMaxWidth(55)
        height: 30 * mydata.length
        color: "yellow"
    }
}