在 QML 中,有没有办法在 Item 上设置 anchor.bottom 而无需设置高度?

Posted

技术标签:

【中文标题】在 QML 中,有没有办法在 Item 上设置 anchor.bottom 而无需设置高度?【英文标题】:In QML, is there a way to set anchor.bottom on an Item without setting height? 【发布时间】:2020-10-28 02:17:51 【问题描述】:

我是 Qt 和 QML 的新手。我见过的示例建议使用 Item 包装组件。我希望项目包含的东西位于应用程序窗口的底部。所以,我将项目的anchor.bottom 设置为parent.bottom。这使得包含的东西不会出现。这个小例子显示了包含的“事物”是矩形的问题。

Window 
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Item 
        anchors 
            bottom: parent.bottom
        

        Rectangle 
            width: 80
            height: 80
            color: "#FF0000"
        
    

我意识到该项目没有明确的高度,其隐含高度最初为 0。我相信当项目没有高度时应用项目的锚点。所以它的底部是它的顶部。所以它的顶部设置为窗口底部,有效地将其定位在窗口下方。但是,包含的矩形有一个高度。在应用锚点之前,项目是否没有动态调整大小?

除了删除 Item 包装器之外,还有其他合适的方法吗?在我的实际代码中,该项目没有包裹一个简单的矩形。它包装了一个 RowLayout,其中包含多个高度不同的东西。我希望 RowLayout 动态调整其高度。

【问题讨论】:

"我看到推荐使用 Item 包装组件"。原因是什么?这不是我会推荐的东西,如果不需要像你的情况一样,恰恰相反。 Nicholas Sherriff 的“Learn Qt 5”是我第一次接触到它的地方。但是,我在其他地方也见过。 【参考方案1】:

Item 中包装组件并不是一个普遍的规则,应该在任何地方都遵循。有时它会有所帮助,但在这种情况下则不然。摆脱您的 Item 应该可以解决您的问题。

Window 
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Rectangle 
        anchors 
            bottom: parent.bottom
        

        width: 80
        height: 80
        color: "#FF0000"
    

如果您将Rectangle 替换为RowLayout,这也应该有效。

【讨论】:

【参考方案2】:

您所要做的就是创建一个填充整个窗口的父 Item 元素,然后将您的项目锚定到该元素。

Window 
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Item 
        anchors.fill: parent
        width: 100
        height: 100

        Rectangle 
            width: 80
            height: 80
            color: "#FF0000"
            /* anchor to the bottom of item */
            anchors.bottom: parent.bottom 
        
     

为什么?我不太确定,但它确实似乎是这样工作的。

--

如果你想包装一个 RowLayout,你会使用相同的基本技术......

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.15
import QtQuick 2.15
 
Window 
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Item 
        anchors.fill: parent
        width: 100
        height: 100
        RowLayout 
            id: layout
            anchors.bottom: parent.bottom
            anchors.top: parent.verticalCenter
            spacing: 6
            Rectangle 
                 color: 'teal'
                 Layout.fillWidth: true
                 Layout.minimumWidth: 50
                 Layout.preferredWidth: 100
                 Layout.maximumWidth: 300
                 Layout.minimumHeight: 150
                 Text 
                      anchors.bottom: parent.bottom
                      text: parent.width + 'x' + parent.height
                 
           
            Rectangle 
                 width: 80
                 height: 80
                 color: "#FF0000"
                 
            

            Rectangle 
                  color: 'plum'
                  Layout.fillWidth: true
                  Layout.minimumWidth: 100
                  Layout.preferredWidth: 200
                  Layout.preferredHeight: 100
                  Text 
                        anchors.bottom: parent.bottom
                        text: parent.width + 'x' + parent.height
                   
             
         
     

【讨论】:

您的行 anchors.fill: parent 与将 widthheight 设置为 100 冲突。 没关系,使用anchors.fill时会忽略宽度和高度,但是如果将widthheight保留为0,那么QML引擎会考虑不是可视元素,因此不会处理任何调整大小事件等,并且通常会实际从内存中完全删除该项目,直到它的大小大于 0,如 Qt 文档中所述 是的,我知道 Qt 会忽略那里的宽度和高度。我只是说这让阅读代码的人感到困惑。我很困惑你说如果没有设置宽度和高度,项目将不会处理任何调整大小事件,即使设置了 anchors.fill。 我不希望 Item wrapper 填充窗口,因为我有 WIndow 的其他子项锚定到 Item 的顶部以填充事物未使用的其余空间项目包含。所以,我想我只需要消除 Item 并直接使用它包含的东西(我原始帖子中的矩形,或我真实代码中的 RowLayout)。 @Josh 实际上,不要消除任何项目,只需添加其他项目作为***项目的子项目,然后将您的代码放入子项目中。这种技术被称为“包装”,这就是他们在谈论用Item 包装时所指的

以上是关于在 QML 中,有没有办法在 Item 上设置 anchor.bottom 而无需设置高度?的主要内容,如果未能解决你的问题,请参考以下文章

如何将C ++类设置为qml中的Item?

如何创建不规则形状的qml组件

如何在QML应用中得到一个Item的所有属性,信号及方法,qmlitem

提问qml中的listview中的item怎么自适应高度

有没有办法在 QML 中设置线性渐变 stepwith

带有自定义滚动条的 QML Listview