【问题标题】:QML Binding loop detected for property width (TextMetrics acts weird)检测到属性宽度的 QML 绑定循环(TextMetrics 行为怪异)
【发布时间】:2019-08-13 09:41:32
【问题描述】:

我遇到了绑定循环问题,代码确实有效,但我想摆脱这些警告。

如果我从 calculateMaxWidth() 函数返回一个常量值,则不会出现警告,但一旦我使用 TextMetrics,事情就会变得糟糕。有趣的是,对于 for 循环中的每个新循环,我都会收到越来越多的警告。如果我将 TextMetrics 创建与销毁一起放在 for 循环中,我会为每个测量的文本收到一个警告。

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"
    }
}

这是默认的 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 矩形:检测到属性“宽度”的绑定循环

【问题讨论】:

    标签: c++ qt user-interface qml


    【解决方案1】:

    分配给 TextMetrics / FontMetrics 属性会以某种方式导致绑定循环警告。但是查询 FontMetrics 的 boundingRect 不会创建分配,因此不会出现警告。在创建 FontMetrics 对象期间,我还必须将字体大小作为属性绑定传递。

    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"
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多