关于qt:当中继器的代表高度更改时调整ColumnLayout

Adjust ColumnLayout when a Repeater's delegate height changes

我已经建立了一个名为test1.qml的文件,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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的文件,定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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具有以下内容:

1
2
3
4
5
6
7
8
9
10
import QtQuick 2.6

Rectangle {
    MouseArea {
        anchors.fill: parent
        onClicked: {
            parent.height += 50
        }
    }
}

我的目标是单击MyRectangle的实例时,它们的高度会发生变化,并且ColumnLayout应该扩大,以便项目保持其间距。

当我运行test.qml时,结果不是我期望的,因为MyRectangle的实例在单击时彼此重叠。但是,test2.qml提供了所需的行为,并且MyRectangle的实例在ColumnLayout增大时保持其间距。

应derM的要求,我认为以下GIF可能有助于更清楚地解释这一点。

test1.qml的(不需要的)行为:

The (undesired) behavior of **test1.qml**

test2.qml的(所需)行为:

The (desired) behavior of **test2.qml**

为什么必须将对象包装在Column中才能获得所需的结果?


原因听起来很奇怪:

[...]Layout系列不仅可以放置对象,还可以调整它们的大小。您不应在其中设置或更改大小。

要执行其工作,当您不使用可用的附加属性设置大小时,它将使用您的Item s的implicitWidth/Height

如果您尚未设置隐式尺寸,而是将新项目添加到布局中,则其隐式尺寸将设置为等于其设置的尺寸。但这不是约束力!因此,如果现在更新height,则implicitHeight将保持原始大小,因此布局不会对更改做出反应。

如果将Column添加到您的委托中,则情况会发生变化:Column根据其子级的边界矩形更新其implicitHeight。如果现在调整Rectangle的高度大小,则Column将适应implicitHeight,而Layout将对更改做出反应。

现在您有以下解决方案:

  • 使用附加的Layout属性来设置和更改大小提示。
  • 使用委托implicitHeight代替height。不过,这可能在语义上是错误的。
  • 当您不需要额外的布局功能(附加的属性和Items的大小等)时,请不要使用ColumnLayout,而只是常规的Column,这似乎是您的问题所在。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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

    }