首页 > 解决方案 > 如何使 GridLayout 响应式?

问题描述

我有一个表单,我想通过以下方式响应窗口的宽度:

这是我的代码:

main.qml

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3

ApplicationWindow {
    id: window
    visible: true
    width: 800 // 1100
    title: "Stack"

    ScrollView {
        anchors.fill: parent

        GridLayout {
            columns: 2

            CVerticalLabel {
                text: "Miscellaneous"
                background: "blue"
                Layout.fillHeight: true
            }

            GridLayout {
                columns: 2

                Text {
                    text: "Company Name"
                    color: "red"
                    font.bold: true
                    font.pointSize: 16
                }

                TextField  {
                    objectName: "company_name"
                    font.bold: true
                    Layout.fillWidth: true
                    implicitHeight: 30
                    implicitWidth: 1000
                }
            }
        }
    }
}

CVerticalLabel.qml

import QtQuick 2.9

Item {
    id: control
    property string text
    property color color: "red"
    property color background: "blue"
    property real bgOpacity: 0.6

    width: 15 * 1.6

    Rectangle {
        anchors.fill: control
        color: control.background
        opacity: control.bgOpacity
    }

    Text {
        color: control.color
        text: control.text
        font.bold: true
        font.pointSize: 10
        width: control.height
        height: control.width
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        rotation: 90
        y: -height
        transformOrigin: Item.BottomLeft
    }
}

该代码产生以下结果:

具有固定宽度、左对齐窗体的窗口

问题是,表单向左对齐并且它的大小总是固定的,即它没有考虑不同的窗口宽度。所以第二列不会被拉伸以填充剩余的可用宽度。

如何达到预期的效果?

标签: qtqml

解决方案


解决方案

为了使GridLayout页面居中在900px窗口宽度超过时的最大宽度,1000px我建议您采用以下解决方案:

  1. 添加 aPage作为您的父级ScrollView

    Page {
        id: page
        anchors.fill: parent
    
        ScrollView {
            ...
        }
    }
    
  2. GridLayout通过考虑其子边界矩形的宽度以及 的宽度来制作动态的左锚边距Page

    anchors.leftMargin: (page.width - childrenRect.width)/2
    

注意:此解决方案类似于此处Flow讨论的居中方式。

例子

这是我为您创建的示例,说明如何更改代码以实施建议的解决方案:

ApplicationWindow {
    id: window
    title: "Stack"
    visible: true
    width: 1400

    Page {
        id: page
        anchors.fill: parent
        property int responsiveWidth: 1000
        property int maximumWidth: 900

        ScrollView {
            anchors.fill: parent

            GridLayout {
                columns: 2

                width: page.width > page.responsiveWidth ? page.maximumWidth : page.width
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.leftMargin: (page.width - childrenRect.width)/2

                CVerticalLabel {
                    text: "Miscellaneous"
                    background: "blue"
                    Layout.fillHeight: true
                }

                GridLayout {
                    columns: 2

                    CTextLabel {
                        text: "Company Name"
                        color: "red"
                    }

                    PanelTextField  {
                        objectName: "company_name"
                        font.bold: true
                        Layout.fillWidth: true
                    }
                }
            }
        }
    }
}

结果

提供的示例产生以下结果:

  • 对于窗口宽度@800px

全角窗体的窗口

  • 对于窗口宽度@1100px

具有 900 像素宽的窗体的窗口


推荐阅读