如何使用QML布局在网格中排列宽高比缩放项?

时间:2017-01-02 18:51:02

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

我有一定长宽比的矩形和具有反长宽比的矩形。我想将它们安排在我选择的网格布局中(不需要是常规网格,相反:我更喜欢可以构建RowLayout和{{1}的解决方案随意)。

我知道我可以使用ColumnLayoutLayout.fillHeight在我的布局中添加缩放项目。不幸的是,我无法正确定义Layout.fillWidth的宽高比。我知道QML Rectangle可以做到这一点(通过它的Image属性),但我认为没有简单的方式做得很好。

非常感谢任何正确方向的帮助或指示!

注意我假设QML布局是要走的路,但是如果有一个只有锚点或普通fillMode / Row设置的功能解决方案,我就是全力以赴! / p>

另请注意,我希望保持两种类型Column的区域相同,就像在实验中看起来一样,这不是那么微不足道......

修改

尝试我的意思,减去相等的面积约束。矩形填充宽度,但在高度上留出空间,因为它们受纵横比和填充宽度的约束。同样应该是高度,但我没有把两者结合起来。

1

3 个答案:

答案 0 :(得分:0)

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

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
            }
        }
    }
}

答案 1 :(得分:0)

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

此矩形将始终遵守其 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
}

希望它可以帮助通过Google搜索到达这里的人们!

答案 2 :(得分:0)

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

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

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

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
            }
        }
    }
}

结果

发布时:

At Launch

拉长:

Stretched narrow

拉伸宽:

Stretched wide