1

I wish to make a prototype screen layout using QML and a GridLayout. I cannot get it to work. I have followed many previous examples here on Stackoverflow but nothing works satisfactorily and its clear I do not understand QML layouts and need some help. (DevEnv: Centos 7.5, Qt 5.11/QtCreator 4.7.1)

I wish to achieve this screen layout (ignore the colours)

Desired Layout

Example 1

import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3


ApplicationWindow {
    visible: true
    visibility: "Maximized"
    title: 'Title'

    GridLayout {
        id: mainLayout
        anchors.fill: parent

        rows: 8
        columns: 12

        Rectangle {
            id: view_A
            color: "lightgreen"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 11
            Layout.rowSpan: 1
            Layout.row: 1
            Layout.column: 1
            Text { text: "view_A" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_B
            color: "yellow"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 5
            Layout.rowSpan: 3
            Layout.row: 2
            Layout.column: 1
            Text { text: "view_B"; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_C
            color: "blue"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 4
            Layout.rowSpan: 3
            Layout.row: 2
            Layout.column: 6
            Text { text: "view_C" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_D
            color: "blueviolet"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 2
            Layout.rowSpan: 5
            Layout.row: 2
            Layout.column: 10
            Text { text: "view_D" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_E
            color: "lightblue"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 3
            Layout.rowSpan: 4
            Layout.row: 5
            Layout.column: 1
            Text { text: "view_E" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_F
            color: "darkorange"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 6
            Layout.rowSpan: 4
            Layout.row: 5
            Layout.column: 4
            Text { text: "view_F" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_G
            color: "seagreen"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 2
            Layout.rowSpan: 2
            Layout.row: 7
            Layout.column: 10
            Text { text: "view_G" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_H
            color: "yellow"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 1
            Layout.rowSpan: 8
            Layout.row: 1
            Layout.column: 12
            Text { text: "view_H" ; anchors.centerIn: parent }
        }
    }
}

This solution comes close, however, the grid elements are not the sizes I specified. For example the top element id: view_A is far taller than desired, as is the width of id: view_H. (Screenshot of results of Example 1 QML code execution )

Failed Element Sizes Example 1

Example 2:

I then tried the solution provided here (How can I create a QML GridLayout with items of proportionate sizes?). This has come as close as I can get but there are ugly spaces between some elements.

// QML Code Example 2

import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3


ApplicationWindow {
    visible: true
    visibility: "Maximized"
    title: 'Title'

    GridLayout {
        id: grid
        anchors.fill: parent
        rowSpacing: 0
        columnSpacing: 0

        rows: 8
        columns: 12

        property double colMultiplier: grid.width / grid.columns
        property double rowMultiplier: grid.height / grid.rows;
        function getElementHeight(element) {
            return element.Layout.rowSpan * rowMultiplier
        }
        function getElementWidth(element) {
            return element.Layout.columnSpan * colMultiplier
        }

        Rectangle {
            id: view_A
            color: "lightgreen"
            Layout.columnSpan: 11
            Layout.rowSpan: 1
            Layout.row: 1
            Layout.column: 1
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_A" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_B
            color: "yellow"
            Layout.columnSpan: 5
            Layout.rowSpan: 3
            Layout.row: 2
            Layout.column: 1
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_B"; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_C
            color: "blue"
            Layout.columnSpan: 4
            Layout.rowSpan: 3
            Layout.row: 2
            Layout.column: 6
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_C" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_D
            color: "blueviolet"
            Layout.columnSpan: 2
            Layout.rowSpan: 5
            Layout.row: 2
            Layout.column: 10
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_D" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_E
            color: "lightblue"
            Layout.columnSpan: 3
            Layout.rowSpan: 4
            Layout.row: 5
            Layout.column: 1
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_E" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_F
            color: "darkorange"
            Layout.columnSpan: 6
            Layout.rowSpan: 4
            Layout.row: 5
            Layout.column: 4
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_F" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_G
            color: "seagreen"
            Layout.columnSpan: 2
            Layout.rowSpan: 2
            Layout.row: 7
            Layout.column: 10
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_G" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_H
            color: "yellow"
            Layout.columnSpan: 1
            Layout.rowSpan: 8
            Layout.row: 1
            Layout.column: 12
            Layout.preferredHeight: grid.getElementHeight(this)
            Layout.preferredWidth:  grid.getElementWidth(this)
            Text { text: "view_H" ; anchors.centerIn: parent }
        }
    }
}

Example 2 Failure

So as can be seen in the resultant screenshot that ther are spaces between some elements that look terrible.

So, if there are any QML experts that can help solve this issue I would really like to hear from you.

kind regards ...

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Gav_at_HRSTS
  • 179
  • 2
  • 11
  • have you tried nested horiz and vert containers instead of trying to force a grid to give you the aspect ratios you want? – Wes Hardaker Jan 30 '19 at 00:59
  • Yes, I tried for a full day using RowLayouts and ColumnLayouts but could not get them to work in any logical fashion so I gave up on them completely and hoped that the GridLayout would be somewhat easier ... – Gav_at_HRSTS Jan 30 '19 at 01:07
  • Actually, I mean `QVBoxLayout` and `QHBoxLayout`. The top layout, in your example, would QHBoxLayout and would contain two items: a QVBoxLayout (we'll call "left" here) and the `view_H` widget. Then the "left" vbox layout would contain the `view_A` widget followed by a new QVBoxLayout, in which would go two VBoxes... you keep dividing til you win! – Wes Hardaker Jan 31 '19 at 00:33

1 Answers1

1

You can add Layout.preferedWidth and Layout.preferedHeight to fix this

GridLayout {
        id: mainLayout
        anchors.fill: parent

        rows: 8
        columns: 12

        Rectangle {
            id: view_A
            color: "lightgreen"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 11
            Layout.rowSpan: 1
            Layout.preferredWidth: 11
            Layout.preferredHeight: 1
            Layout.row: 1
            Layout.column: 1
            Text { text: "view_A" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_B
            color: "yellow"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 5
            Layout.rowSpan: 3
            Layout.preferredWidth: 5
            Layout.preferredHeight: 3
            Layout.row: 2
            Layout.column: 1
            Text { text: "view_B"; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_C
            color: "blue"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 4
            Layout.rowSpan: 3
            Layout.preferredWidth: 4
            Layout.preferredHeight: 3
            Layout.row: 2
            Layout.column: 6
            Text { text: "view_C" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_D
            color: "blueviolet"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 2
            Layout.rowSpan: 5
            Layout.preferredWidth: 2
            Layout.preferredHeight: 5
            Layout.row: 2
            Layout.column: 10
            Text { text: "view_D" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_E
            color: "lightblue"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 3
            Layout.rowSpan: 4
            Layout.preferredWidth: 3
            Layout.preferredHeight: 4
            Layout.row: 5
            Layout.column: 1
            Text { text: "view_E" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_F
            color: "darkorange"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 6
            Layout.rowSpan: 4
            Layout.preferredWidth: 6
            Layout.preferredHeight: 4
            Layout.row: 5
            Layout.column: 4
            Text { text: "view_F" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_G
            color: "seagreen"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 2
            Layout.rowSpan: 2
            Layout.preferredWidth: 2
            Layout.preferredHeight: 2
            Layout.row: 7
            Layout.column: 10
            Text { text: "view_G" ; anchors.centerIn: parent }
        }

        Rectangle {
            id: view_H
            color: "yellow"
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.columnSpan: 1
            Layout.rowSpan: 8
            Layout.preferredWidth: 1
            Layout.preferredHeight: 8
            Layout.row: 1
            Layout.column: 12
            Text { text: "view_H" ; anchors.centerIn: parent }
        }
    }

Result :

enter image description here

Skogandr
  • 133
  • 6