当 Repeater 的委托高度改变时调整 ColumnLayout
Adjust ColumnLayout when a Repeater's delegate height changes
我创建了一个名为 test1.qml 的文件,其中包含以下内容:
import QtQuick 2.6
import QtQuick.Layouts 1.3
Rectangle {
width: 800; height: 1000;
ColumnLayout {
anchors.centerIn: parent
// Header goes here
Repeater {
model: 3
delegate: MyRectangle {
width: 150
height: width
color: "#44ff0000"
}
}
// Footer goes here
}
}
我还设置了一个名为 test2.qml 的文件,定义如下:
import QtQuick 2.6
import QtQuick.Layouts 1.3
Rectangle {
width: 800; height: 1000;
ColumnLayout {
anchors.centerIn: parent
// Header goes here
Repeater {
model: 3
delegate: Column {
MyRectangle {
width: 150
height: width
color: "#44ff0000"
}
}
}
// Footer goes here
}
}
最后,MyRectangle.qml有以下内容:
import QtQuick 2.6
Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
parent.height += 50
}
}
}
我的目标是当 MyRectangle 的实例被点击时,它们的高度会改变,并且 ColumnLayout 应该放大以便项目保持他们的间距。
当我运行test.qml时,结果不是我所期望的,因为MyRectangle[=50的实例=] 在点击时相互重叠。但是,test2.qml 给出了所需的行为,并且 MyRectangle 的实例将它们的间距保持为 ColumnLayout 放大.
应derM的要求,我认为下面的GIF可能有助于更清楚地解释这一点。
test1.qml的(不希望的)行为:
test2.qml的(期望)行为:
为什么我必须将对象包装在 列 中才能获得所需的结果?
原因可能听起来很奇怪:
[...]Layout
-family 不仅可以排列对象,还可以调整对象的大小。您不应该在其中设置或更改尺寸。
为了完成它的工作,当您不使用可用的附加属性来设置尺寸时,它将使用您的 Item
的 implicitWidth/Height
。
如果您没有设置隐式尺寸,则在将新项目添加到布局时,它们的隐式尺寸将被设置为等于它们的设置尺寸。但这不是绑定!因此,如果您现在更新 height
,implicitHeight
将保持原始大小,因此布局不会对更改做出反应。
如果将 Column
添加到委托中,情况会发生变化:Column
根据其子项的边界矩形更新其 implicitHeight
。如果您现在调整 Rectangle
s 的高度,Column
将适应 implicitHeight
而 Layout
将对更改做出反应。
现在你有以下解决方案:
- 使用附加的
Layout
属性 来设置和更改尺寸提示。
- 使用代表
implicitHeight
而不是 height
。不过这在语义上可能是错误的。
- 当您不需要额外的布局功能(附加属性和调整项目大小等)时,不要使用
ColumnLayout
,而只使用常规 Column
,这似乎你的问题就是这样。
Column {
anchors.centerIn: parent
spacing: 5
// Header goes here
Repeater {
model: 3
delegate:
Rectangle {
width: 150
height: width
color: "#44ff0000"
MouseArea {
anchors.fill: parent
onClicked: {
console.log(parent.implicitHeight)
parent.height += 50
}
}
}
}
// Footer goes here
}
我创建了一个名为 test1.qml 的文件,其中包含以下内容:
import QtQuick 2.6
import QtQuick.Layouts 1.3
Rectangle {
width: 800; height: 1000;
ColumnLayout {
anchors.centerIn: parent
// Header goes here
Repeater {
model: 3
delegate: MyRectangle {
width: 150
height: width
color: "#44ff0000"
}
}
// Footer goes here
}
}
我还设置了一个名为 test2.qml 的文件,定义如下:
import QtQuick 2.6
import QtQuick.Layouts 1.3
Rectangle {
width: 800; height: 1000;
ColumnLayout {
anchors.centerIn: parent
// Header goes here
Repeater {
model: 3
delegate: Column {
MyRectangle {
width: 150
height: width
color: "#44ff0000"
}
}
}
// Footer goes here
}
}
最后,MyRectangle.qml有以下内容:
import QtQuick 2.6
Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
parent.height += 50
}
}
}
我的目标是当 MyRectangle 的实例被点击时,它们的高度会改变,并且 ColumnLayout 应该放大以便项目保持他们的间距。
当我运行test.qml时,结果不是我所期望的,因为MyRectangle[=50的实例=] 在点击时相互重叠。但是,test2.qml 给出了所需的行为,并且 MyRectangle 的实例将它们的间距保持为 ColumnLayout 放大.
应derM的要求,我认为下面的GIF可能有助于更清楚地解释这一点。
test1.qml的(不希望的)行为:
test2.qml的(期望)行为:
为什么我必须将对象包装在 列 中才能获得所需的结果?
原因可能听起来很奇怪:
[...]Layout
-family 不仅可以排列对象,还可以调整对象的大小。您不应该在其中设置或更改尺寸。
为了完成它的工作,当您不使用可用的附加属性来设置尺寸时,它将使用您的 Item
的 implicitWidth/Height
。
如果您没有设置隐式尺寸,则在将新项目添加到布局时,它们的隐式尺寸将被设置为等于它们的设置尺寸。但这不是绑定!因此,如果您现在更新 height
,implicitHeight
将保持原始大小,因此布局不会对更改做出反应。
如果将 Column
添加到委托中,情况会发生变化:Column
根据其子项的边界矩形更新其 implicitHeight
。如果您现在调整 Rectangle
s 的高度,Column
将适应 implicitHeight
而 Layout
将对更改做出反应。
现在你有以下解决方案:
- 使用附加的
Layout
属性 来设置和更改尺寸提示。 - 使用代表
implicitHeight
而不是height
。不过这在语义上可能是错误的。 - 当您不需要额外的布局功能(附加属性和调整项目大小等)时,不要使用
ColumnLayout
,而只使用常规Column
,这似乎你的问题就是这样。
Column {
anchors.centerIn: parent
spacing: 5
// Header goes here
Repeater {
model: 3
delegate:
Rectangle {
width: 150
height: width
color: "#44ff0000"
MouseArea {
anchors.fill: parent
onClicked: {
console.log(parent.implicitHeight)
parent.height += 50
}
}
}
}
// Footer goes here
}