检测到属性宽度的 QML 绑定循环(TextMetrics 行为怪异)
Posted
技术标签:
【中文标题】检测到属性宽度的 QML 绑定循环(TextMetrics 行为怪异)【英文标题】:QML Binding loop detected for property width (TextMetrics acts weird) 【发布时间】: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 矩形:检测到属性“宽度”的绑定循环
【问题讨论】:
【参考方案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"
【讨论】:
以上是关于检测到属性宽度的 QML 绑定循环(TextMetrics 行为怪异)的主要内容,如果未能解决你的问题,请参考以下文章