【问题标题】:How can I use QML Layouts to arrange aspect ratio scaled items in a grid?如何使用 QML 布局在网格中排列纵横比缩放的项目?
【发布时间】:2021-07-11 06:20:16
【问题描述】:

我有一定纵横比的矩形和反纵横比的矩形。我想将它们排列在我选择的网格布局中(不需要是常规网格,相反:我更喜欢可以随意构建RowLayouts 和ColumnLayouts 的解决方案)。

我知道我可以使用 Layout.fillHeight 和 Layout.fillWidth 在我的布局中缩放项目。不幸的是,我找不到为我的Rectangles 正确定义纵横比的方法。我知道 QML Image 可以做到这一点(通过其 fillMode 属性),但我没有看到 简单 方法可以很好地做到这一点。

任何正确方向的帮助或指示将不胜感激!

请注意,我假设 QML Layouts 是可行的方法,但如果有一个功能性解决方案只有锚点或简单的 Row/Column 设置,我完全赞成!

另外请注意,我更愿意将两种类型的Rectangle 的面积保持相同,因为在实验时似乎,这并不是那么微不足道...

编辑

尝试我的意思,减去等面积约束。矩形填充宽度,但在高度上留出空间,因为它们受到纵横比和填充宽度的限制。高度也应该如此,但我无法将两者结合起来。

【问题讨论】:

  • 您能否提供一张图片来描述您想要实现的目标?这将有助于理解并希望能回答您的问题。
  • @GrecKo 尝试覆盖了我大约 1/3 的约束。我正在向您展示满意的那个;-)。
  • 作为一张图片,我的意思是一张满足您所有限制的图片,它可以在绘画中完成,而不必在 QML 中完成,否则您不需要太多帮助;)跨度>
  • 好吧,我需要其中几个才能真正显示所有这些。我稍后会尝试制作它们!
  • 如果您想要的布局无法完成​​,您可以查看github.com/Ableton/aqt-cassowary。我还没有真正使用它,所以我无法提供更多细节,但它似乎是一个很好的线索。

标签: qt layout qml aspect-ratio layout-anchor


【解决方案1】:

几天来,我一直在努力寻找正确的方法。 我找不到任何工作示例,所以我自己写了。

此矩形将始终遵守其 aimedRatio 并保持其边距。 这里的诀窍是针对不同的情况进行处理:父母比例是否大于目标比例。在一种情况下,您将宽度绑定到父级并根据设置高度。在另一种情况下,您可以采用其他方式。

Rectangle {
    color  : 'green'

    // INPUTS
    property double  rightMargin    : 20
    property double  bottomMargin   : 20
    property double  leftMargin     : 20
    property double  topMargin      : 20
    property double  aimedRatio     : 3/4

    // SIZING
    property double  availableWidth  : parent.width  - rightMargin  - leftMargin
    property double  availableHeight : parent.height - bottomMargin - topMargin

    property bool    parentIsLarge   : parentRatio > aimedRatio

    property double  parentRatio     : availableHeight / availableWidth

    height : parentIsLarge ? width * aimedRatio :  availableHeight
    width  : parentIsLarge ? availableWidth     :  height / aimedRatio

    anchors.top        : parent.top
    anchors.topMargin  : topMargin
    anchors.left       : parent.left
    anchors.leftMargin : leftMargin
}

希望它能帮助通过谷歌搜索到达这里的人!

【讨论】:

    【解决方案2】:

    我确实赞成@CharlesSALA 的答案(因为它有效!),但我认为我也会根据布局提供替代答案。

    AspectItem 负责提供正确的边距以保持宽度,使用 implicitWidth。 Layout 负责提供正确的边距以保持高度,使用 Layout.maximumHeight。

    这同样适用于GridLayout 代替ColumnLayout 和RowLayout。结果略有不同,因为列必须在所有行中保持对齐,但在这两种情况下,矩形的纵横比都会根据需要保留。

    AspectItem.qml

    import QtQuick 2.11
    
    Item {
        id: container
        property real aimedRatio: 3/4
        property alias color: content.color
        implicitWidth: height*container.aimedRatio
        implicitHeight: width/container.aimedRatio
    
        Rectangle {
            id: content
            anchors.horizontalCenter: container.horizontalCenter
    
            height: container.height
            implicitWidth: height*container.aimedRatio
        }
    }
    

    ma​​in.qml

    import QtQuick 2.11
    import QtQuick.Controls 2.4
    import QtQuick.Layouts 1.11
    
    ApplicationWindow {
        id: window
        visible: true
        width: 800
        height: 800
        y: 0
    
        ColumnLayout {
            anchors.fill: parent
    
            RowLayout {
                width: parent.width
                AspectItem {
                    color: "darkseagreen"
                    aimedRatio: 1/2
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
    
                AspectItem {
                    color: "seagreen"
                    aimedRatio: 2/1
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
    
                AspectItem {
                    color: "lightseagreen"
                    aimedRatio: 1/2
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
            }
    
            RowLayout {
                width: parent.width
                AspectItem {
                    color: "darkcyan"
                    aimedRatio: 2/1
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
    
                AspectItem {
                    color: "cyan"
                    aimedRatio: 1/2
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
    
                AspectItem {
                    color: "lightcyan"
                    aimedRatio: 2/1
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
            }
    
            RowLayout {
                width: parent.width
                AspectItem {
                    color: "darksalmon"
                    aimedRatio: 1/2
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
    
                AspectItem {
                    color: "salmon"
                    aimedRatio: 2/1
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
    
                AspectItem {
                    color: "lightsalmon"
                    aimedRatio: 1/2
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.maximumHeight: implicitHeight
                }
            }
        }
    }
    

    结果

    发布时:

    拉窄:

    拉宽:

    【讨论】:

      【解决方案3】:

      您可以使用属性绑定将矩形的width 与height 使用纵横比绑定,如下所示,

      import QtQuick 2.5
      import QtQuick.Window 2.2
      import QtQuick.Layouts 1.0
      
      Window {
          id: root
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
          property int minWidth: 150
          property int maxWidth: 300
          property int minHeight: 150
          property int maxHeight: 250
          property int rowWidth: root.width/3 //Change accordingly the width of each child item w.r.t. the width of the root.
          Row {
              id: layout
              anchors.fill: parent
              spacing: 6
              Rectangle {
                  color: 'red'
                  // 4/3 is the aspect ratio of the first Rectangle
                  height: (3*width/4)<root.minHeight ? root.minHeight : ( (3*width/4)>root.maxHeight ? root.maxHeight : 3*width/4 )
                  width: (root.rowWidth) < root.minWidth ? root.minWidth : ( root.rowWidth > root.maxWidth ? root.maxWidth : root.rowWidth)
                  Text {
                      anchors.centerIn: parent
                      text: parent.width + 'x' + parent.height
                  }
              }
              Rectangle {
                  color: 'green'
                  // 3/4 is the aspect ratio of the second Rectangle
                  height: (4*width/3)<root.minHeight ? root.minHeight : ( (4*width/3)>root.maxHeight ? root.maxHeight : 4*width/3 )
                  width: (root.rowWidth) < root.minWidth ? root.minWidth : ( root.rowWidth > root.maxWidth ? root.maxWidth : root.rowWidth)
                  Text {
                      anchors.centerIn: parent
                      text: parent.width + 'x' + parent.height
                  }
              }
          }
      }
      

      【讨论】:

      • 这不会保持矩形的纵横比。我只是得到固定在边缘的矩形。
      • @rubenvb 宽度与高度的比率在调整窗口大小时保持不变。这不是你想要的吗?
      • 将您的代码复制到新的 Qt Creator QML 应用程序时,我看不到这种行为:/。这就是我能告诉你的。哦,这是在 Mac 上,并且使用问题中提到的 Qt 5.5。不确定这些是否相关。
      • 你能告诉我你得到的确切输出是什么,或者它与你想要的有什么不同吗?
      猜你喜欢
      • 2017-05-07
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2020-04-04
      • 2022-08-24
      相关资源
      最近更新 更多