QML 行的大小不适合内容

QML Row not sizing to fit contents

我定义了几个包含行的 QML 类(MyFrame 和 MyGroup)。我用两个 MyGroup 以及两个矩形填充 MyFrame 行。每个 MyGroup 还包含两个矩形。

当运行时,我只看到彼此相邻的绿色和粉红色矩形,如下所示。 MyGroup 中的所有矩形的宽度均为 0(我认为)。

如果我在 MyGroup 中硬编码一个 width:130,那么所有内容都会正常显示,如下所示。

为什么每个“MyGroup”对象不调整其宽度以容纳其中的两个矩形?如何修复我的代码,使 MyGroup 调整大小以适合其行内容?

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    width: 1024
    height: 768
    visible: true

    MyFrame {
        MyGroup {
            Rectangle {
                width: 50
                height: 50
                color: "orange"
            }
            Rectangle {
                width: 50
                height: 50
                color: "black"
            }
        }
        MyGroupDivider {}
        MyGroup {
            Rectangle {
                width: 50
                height: 50
                color: "red"
            }
            Rectangle {
                width: 50
                height: 50
                color: "blue"
            }
        }
        MyGroupDivider {}
        Rectangle {
            width: 60
            height: 60
            color: "green"
        }
        Rectangle {
            width: 60
            height: 60
            color: "pink"
        }
    }

}

MyFrame.qml

import QtQuick 2.0
Rectangle {
    default property alias contents: frameContents.children
    anchors {
        top: parent.top
        left: parent.left
        right: parent.right
    }
    height: 100
    Row {
        anchors {
            fill: parent
            margins: 5
        }
        id: frameContents
    }
}

MyGroup.qml

import QtQuick 2.0

Item {
    default property alias contents: groupContents.children
    anchors {
        top: parent.top
        bottom: parent.bottom
    }
    Row {
        anchors {
            fill: parent
        }
        id: groupContents
        spacing: 5
    }
}

问题在于您的设置和锚点的使用强制从上到下调整大小,但涉及 MyGroup 组件的宽度时除外。由于您没有在那里设置宽度,该项目最终宽度 == 0。

当您希望根据内容调整大小而不是 parent 的尺寸时,您必须采用如下方法:

MyGroup.qml:

import QtQuick 2.0

Item {
    default property alias contents: groupContents.children
    implicitHeight: groupContents.implicitHeight
    implicitWidth: groupContents.implicitWidth

    Row {
        id: groupContents
        spacing: 5
    }
}

关于这里发生的事情要记住的一些事情。

  1. “隐式”尺寸声明项目的首选宽度和高度。这些通常由容器检查、尊重和反映。
  2. 项目的大小不会包含它们的 children 除非您特别要求它们这样做。另一方面,像 Row 这样的容器确实设置了它们的隐式大小以反映它们的隐式大小 children.
  3. 当通过 children 从内(内容)向外约束时,它是从层次结构的底部到您需要的隐式大小。
  4. 当通过 parents 从外向内约束时,它一直向下锚定,直到您到达使用隐式大小的实例。请注意,锚定会覆盖隐式大小行为。

许多应用程序需要混合使用自下而上的隐式调整大小和自上而下的锚定大小。在复杂的情况下恰到好处可以是一门艺术。

标准控件要么具有本机隐式大小,要么是一个容器,隐式大小将反映它们 children。如果您自己制作 containers/widgets,则必须自己管理这些复杂性。例如,如果 Row 是顶级 object 并消除 non-container 项,MyGroup 可能会更好。

另一条注释可能对此造成混淆。默认情况下 Item::clip 为假。这意味着您仍然可以看到 0px X 0px 项目的 children,除非它们在 Z 方向上被另一个 object 覆盖(如本题中的情况)。

因此,有时在调试奇怪的布局问题时设置 clip = true 会有所帮助。