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