Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt QML列:可能的QQuickItem::polish()循环_Qt_Qml - Fatal编程技术网

Qt QML列:可能的QQuickItem::polish()循环

Qt QML列:可能的QQuickItem::polish()循环,qt,qml,Qt,Qml,下面的代码有两个问题 如果我在QML列中使用填充,我会收到以下消息: QML Column: possible QQuickItem::polish() loop 应用程序将变得无响应。此外,如果我不使用锚定,问题不会出现,但列中的矩形不会被拉伸 如果使用锚点,列的implicitWidth和implicitHeight将为零,这将导致不会显示矩形 Qt文档说明: 此外,由于列会自动垂直定位其子项,因此列中的子项不应使用“顶部”、“底部”、“锚定”和“垂直中心”、“填充”或“中心定位”来设

下面的代码有两个问题

  • 如果我在QML列中使用填充,我会收到以下消息:

    QML Column: possible QQuickItem::polish() loop
    
    应用程序将变得无响应。此外,如果我不使用锚定,问题不会出现,但列中的矩形不会被拉伸

  • 如果使用锚点,列的implicitWidth和implicitHeight将为零,这将导致不会显示矩形

  • Qt文档说明:

    此外,由于列会自动垂直定位其子项,因此列中的子项不应使用“顶部”、“底部”、“锚定”和“垂直中心”、“填充”或“中心定位”来设置其y位置或垂直锚定自身

    这意味着不禁止水平锚定(左/右)

    你知道会出什么问题吗

    Rectangle {
        anchors.fill: parent
        color: "green"
        Rectangle {
            anchors.centerIn: parent
            implicitWidth: col.implicitWidth
            implicitHeight: col.implicitHeight
            color: "blue"
            Column {
                spacing: 10
                //padding: 10 // causes: QML Column: possible QQuickItem::polish() loop
                id: col
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    implicitWidth: 100
                    implicitHeight: 25
                }
                Rectangle {
                    //anchors.left: parent.left // uncommenting these anchors will result that the column's implicitWidth and implicitHeight will be 0
                    //anchors.right: parent.right
                    implicitWidth: 200
                    implicitHeight: 25
                }
                Component.onCompleted: console.log("column, imp width: " + implicitWidth + ", imp height: " + implicitHeight)
            }
        }
    }
    
    衬垫 将图元附着到柱的左边缘和右边缘, 但是,然后告诉列它应该将其元素放置在距离该边框10像素的位置

    然后,它们开始互相“打架”,导致布局更新,从而触发彼此

    您需要放置一个中间元素来处理填充,如下所示:

    Column{ padding: 10; Column{ id: col; Rectangle{}; Rectangle{}; } }
    
    锚定 让我们看看到底发生了什么

    我在每个元素中插入了一些调试代码:

    property string name: "..."//I named them: "green_rect", "blue_rect", "col", "top_rect", "bottom_rect"
    onWidthChanged: console.log(name + " changed: w=" + width)
    ....
    property string mydbgstr: "top_rect w=" + width + " h=" + height + " iw=" + implicitWidth + " ih=" + implicitHeight
    onMydbgstrChanged: console.log(mydbgstr)
    
    当任何属性更改时,它将打印一个字符串

    我的窗户是500x500

    初始布局-在所有情况下都保持不变:

    // property change notifications removed since they are not interesting yet
    qml: bottom_rect w=200 h=25 iw=200 ih=25
    qml: top_rect w=100 h=25 iw=100 ih=25
    qml: col w=0 h=0 iw=0 ih=0
    qml: blue_rect w=0 h=0 iw=0 ih=0
    qml: green_rect w=0 h=0 iw=0 ih=0
    
    好的,锚还没有应用,柱还没有计算它的大小,所以元素只是假设h=ih w=iw

    之后,我们看到了不同的结论:

    顶部和底部矩形的锚点均已注释: 结果:

    ▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    ▀▀▀▀▀▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    按预期工作:列根据组合的子项大小计算其大小, 然后,周围的元素也假定该大小

    只有top rect的锚未注释: 结果:

    ▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    ▀▀▀▀▀▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    两个未注释的: 结果:绿色窗口

    结论 列宽取决于最大元素宽度,但元素宽度被锚定到列,因此它有鸡和蛋的问题,但由于它是间接的,并且也会导致初始零大小持续存在,因此Qt无法检测绑定循环,相反,元素保持折叠

    这实际上意味着QtQuick不够“聪明”,无法在这种情况下正确定位项目。必须为其中一个项目或列指定实际宽度

    ColumnLayout
    更聪明一点,因为它可以指定最小、最大和首选大小,所以您可能应该使用它而不是
    Column
    。我知道你已经知道如何使用它了,所以我在这里不详细介绍

    或者,命令式代码可以用来确定元素的最大宽度,并将col的宽度设置为该宽度。如果需要,它还可以设置其他元素的宽度。

    Padding 将图元附着到柱的左边缘和右边缘, 但是,然后告诉列它应该将其元素放置在距离该边框10像素的位置

    然后,它们开始互相“打架”,导致布局更新,从而触发彼此

    您需要放置一个中间元素来处理填充,如下所示:

    Column{ padding: 10; Column{ id: col; Rectangle{}; Rectangle{}; } }
    
    锚定 让我们看看到底发生了什么

    我在每个元素中插入了一些调试代码:

    property string name: "..."//I named them: "green_rect", "blue_rect", "col", "top_rect", "bottom_rect"
    onWidthChanged: console.log(name + " changed: w=" + width)
    ....
    property string mydbgstr: "top_rect w=" + width + " h=" + height + " iw=" + implicitWidth + " ih=" + implicitHeight
    onMydbgstrChanged: console.log(mydbgstr)
    
    当任何属性更改时,它将打印一个字符串

    我的窗户是500x500

    初始布局-在所有情况下都保持不变:

    // property change notifications removed since they are not interesting yet
    qml: bottom_rect w=200 h=25 iw=200 ih=25
    qml: top_rect w=100 h=25 iw=100 ih=25
    qml: col w=0 h=0 iw=0 ih=0
    qml: blue_rect w=0 h=0 iw=0 ih=0
    qml: green_rect w=0 h=0 iw=0 ih=0
    
    好的,锚还没有应用,柱还没有计算它的大小,所以元素只是假设h=ih w=iw

    之后,我们看到了不同的结论:

    顶部和底部矩形的锚点均已注释: 结果:

    ▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    ▀▀▀▀▀▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    按预期工作:列根据组合的子项大小计算其大小, 然后,周围的元素也假定该大小

    只有top rect的锚未注释: 结果:

    ▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    ▀▀▀▀▀▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    两个未注释的: 结果:绿色窗口

    结论 列宽取决于最大元素宽度,但元素宽度被锚定到列,因此它有鸡和蛋的问题,但由于它是间接的,并且也会导致初始零大小持续存在,因此Qt无法检测绑定循环,相反,元素保持折叠

    这实际上意味着QtQuick不够“聪明”,无法在这种情况下正确定位项目。必须为其中一个项目或列指定实际宽度

    ColumnLayout
    更聪明一点,因为它可以指定最小、最大和首选大小,所以您可能应该使用它而不是
    Column
    。我知道你已经知道如何使用它了,所以我在这里不详细介绍


    或者,命令式代码可以用来确定元素的最大宽度,并将col的宽度设置为该宽度。如果需要,它还可以设置其他元素的宽度。

    QML列更像定位器,在我的情况下,它在调整其子元素的大小方面不是很好

    尝试使用ColumnLayout,这在某种程度上解决了问题,但产生了大量警告消息,因为ColumnLayout不是直接生成的,而是从QQuickLayout派生的,在QQuickLayout中检查锚定并转储此警告消息:“在由布局管理的项目上检测到锚定。这是未定义的行为;请改用layout.alignment。”

    最后,我在QML中做了一个变通方法,它利用隐式长度大于零的元素之间的统一填充和间距

    它可以用作常规QML元素

    这是根据杰克·怀特的建议修改的答案

    结果:

    ▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    
    ▀▀▀▀▀▀▀▀▀▀
    ▀▀▀▀▀▀▀▀▀▀
    

    QML列更像一个定位器,在我的情况下,它在调整其子项的大小方面不是很好

    尝试使用ColumnLayout,这在某种程度上解决了问题,但产生了大量警告消息,因为ColumnLayout不是直接生成的,而是从QQuickLayout派生的,在QQuickLayout中检查锚定并转储此警告消息:“在由布局管理的项目上检测到锚定。这是不可更改的。”