QML GroupBox:检测到属性“implicitWidth”的绑定循环

Posted

技术标签:

【中文标题】QML GroupBox:检测到属性“implicitWidth”的绑定循环【英文标题】:QML GroupBox: Binding loop detected for property "implicitWidth" 【发布时间】:2018-07-17 16:32:41 【问题描述】:

我正在尝试在 QQuickWidget 中加载一些 QML 表单并不断收到:QML GroupBox: Binding loop detected for property "implicitWidth" 简化的 QML 是:

import QtQuick 2.4
import QtQuick.Controls 1.2

GroupBox 
    id: root
    title: qsTr("1")

    Column 
        id: column1
        width: parent.width

        ComboBox 
            id: cbComboBox
            width: parent.width
            currentIndex: 0
            editable: false
        

        GroupBox 
            id: groupBox
            title: "test"
            width: parent.width //the problem
            Label 
                text:"1"
                width: parent.width
            

        
    

由于某种原因,我似乎无法将 parent.widthcbComboBox.width 用于 groupBox。 root.width 工作但太宽了。我错过了什么?我需要嵌套的 GroupBox 具有最大宽度(带间距)。

【问题讨论】:

你使用什么版本的 Qt? 我看到问题不是groupbox而是Column,它将Column的宽度设置为固定值,您会看到它不再抛出错误。 @eyllanesc,5.9.5 @eyllanesc,这有帮助,但是 1)我不明白问题的根源 2)新的列宽限制了嵌套 GroupBox 的宽度。我需要它几乎是最大的。实际上整个 QQuickWidget 被放置在垂直对齐的面板中,该面板可以按宽度调整大小,所以我需要 QML 内容的宽度不固定。 【参考方案1】:

根据Qt GroupBox QML Type documentation

GroupBox 的隐式大小是根据其内容的大小计算得出的。

这意味着 GroupBox 将自动使用其子级的大小来计算自己的大小。 在您的情况下,唯一的孩子是宽度等于 GroupBox 宽度的列。我认为这就是导致绑定循环的原因。

如果您按照@eyllanesc 所说的那样设置Column 的宽度,则绑定循环将消失。

我宁愿在 QML 部分定义 GroupBox 的隐式宽度(默认宽度)。在我的示例中,隐式宽度为 100px,但可以根据子项(ComboBox、其他 GroupBox、...)的宽度计算得出。

// MyGroupBox.qml
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.2

GroupBox 
    title: qsTr("1")
    implicitWidth: 100
    Column 
        id: column1
        width: parent.width
        ComboBox 
            id: cbComboBox
            currentIndex: 0
            editable: false
            width: parent.width
        
        GroupBox 
            id: groupBox
            title: "test"
            width: parent.width
            Label 
                text: "1"
            
        
    

并且可以通过更改根对象的宽度直接从 C++ 中根据您的项目设置实际宽度。

// main.cpp
#include <QtQuickWidgets/QQuickWidget>
#include <QQuickItem>
#include <QtWidgets>

int main(int argc, char *argv[])

    QApplication app(argc, argv);
    QQuickWidget *view = new QQuickWidget;
    view->setSource(QUrl::fromLocalFile("://MyGroupBox.qml"));
    view->rootObject()->setWidth(800);
    view->show();
    return app.exec();

【讨论】:

这种方法在通过 QQuickWidget 加载 qml 的情况下没有帮助...在这种情况下 qml 的根项将是 GroupBox 并且它不能使用对parent 的引用。我目前的做法是在父QWidget中声明Q_PROPERTY(int width READ width NOTIFY widthChanged)signals: void widthChanged();,然后用if (QQmlEngine* eng = quickWidget-&gt;engine()) if (QQmlContext* cntx = eng-&gt;rootContext()) cntx-&gt;setContextProperty("rootWidget", this); 将指向它的指针传播到QML,然后在QML GroupBox的width: rootWidget.width中设置@ 如果你可以用这个更新你的答案或者在 QQuickWidget 的情况下提出更好的方法,我会接受这个答案。 考虑到使用 QQuickWidget,我的答案已更新。

以上是关于QML GroupBox:检测到属性“implicitWidth”的绑定循环的主要内容,如果未能解决你的问题,请参考以下文章

检测到属性宽度的 QML 绑定循环(TextMetrics 行为怪异)

QML ListView:检测到属性“高度”的绑定循环

QML:在没有双重分配的情况下检测到绑定循环

QML:在派生类中使属性只读

求教QML RadioButton单选问题

QML:在派生类中使属性只读