【问题标题】:QML GroupBox: Binding loop detected for property "implicitWidth"QML GroupBox:检测到属性“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 内容的宽度不固定。

标签: qt qml qt-quick


【解决方案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,我的答案已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多