Nmaster88
Nmaster88

Reputation: 1605

How to make GridLayout responsive?

I have a form that I want to be responsive with regard to the width of the window in the following way:

Here is my code:

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

The code produces the following result:

Window with a fixed-width, left-aligned form

The problem is, that the form is aligned to the left and its size is always fixed, i.e. it does not take into account the different window widths. So the second column is not stretched to fill the rest of the available width.

How to achieve the desired result?

Upvotes: 0

Views: 1245

Answers (1)

scopchanov
scopchanov

Reputation: 8429

Solution

In order to make the GridLayout centered on the page with a maximum width of 900px when the window width exceeds 1000px I would suggest you the following solution:

  1. Add a Page as a parent of your ScrollView:

    Page {
        id: page
        anchors.fill: parent
    
        ScrollView {
            ...
        }
    }
    
  2. Make the left anchor margin of the GridLayout dynamic by taking into account the width of the bounding rectangle of its children, as well as the width of the Page:

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

Note: This solution is similar to the way Flow is being centered, as discussed here.

Example

Here is an example I have created for you of how your code could be changed in order to implement the proposed solution:

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

Result

The provided example produces the following results:

  • for window width @800px

Window with a full-width form

  • for window width @1100px

Window with a 900px-wide form

Upvotes: 1

Related Questions