Introducing Qt Quick Layouts

If you want to create a QML application where the UI responds well to window resizing, the toolbox that Qt Quick offers has been somewhat limited. Qt 5.1 will offer the new Qt Quick types RowLayout, ColumnLayout and GridLayout for this purpose.

Background

Up until Qt 5.1, positioners and anchors have been the only Qt Quick tools available for arranging items in the UI.

Positioners are convenient for adding many items, but not always helpful for creating a resizable UI since they (as the name implies - surprise, surprise) only positions the items - the widths and heights are kept the same.

Anchors allows a bit more flexibility, at the price of verbosity. With anchors you can make an item stretch by binding one edge to the corresponding edge of the parent, and you set up a similar binding on the items' opposite edge. However, you cannot make several items distribute themselves evenly if the window is resized.

The last option is to do the manual layouting yourself. This offers great flexibility, but it can be verbose, cumbersome and error-prone. During the development of Qt Quick Controls, we wanted to improve this and decided to provide a better and more convenient layout system.

import QtQuick.Layouts 1.0

By including the above import you will have RowLayout, ColumnLayout and GridLayout available in your toolbox. These layouts behave very much like their sisters found in the QtWidgets module: QHBoxLayout, QVBoxLayout and QGridLayout. It also tries to match the API of the Row, Grid and Column QML elements where it makes sense. So, if you are familiar with any of these APIs, you will find Qt Quick Layouts easy to grasp.

Alignment of items inside a cell can be specified with the Layout.alignment property.

Spans across rows or columns can be specified with the Layout.rowSpan and Layout.columnSpan properties.

Grid coordinates can be specified with the Layout.row and Layout.column properties.

Resizable items can be specified with the Layout.fillWidth and Layout.fillHeight properties. This was the main goal of the Qt Quick Layouts.

Minimum, Preferred and Maximum sizes can be specified with Layout.minimumWidth, Layout.preferredWidth and Layout.maximumWidth  properties ("Width" can be replaced with "Height" for specifying similar constraints to the height).

The feature set it adds might not look like a lot, but the fact that you can have both non-stretching items and stretching items in the same layout makes things easier and more intuitive in many cases.

Example

Suppose we need to create a ToolBar with two buttons and a slider that occupies the remaining space. When resizing, the extra space will be allocated to the slider.
Without Qt Quick Layouts, the solution with least code would probably be a mix between using a Row and using anchors:
ToolBar {
Row {
id: row
        spacing: 2
        anchors.verticalCenter: parent.verticalCenter
        ToolButton { iconSource: "images/go-previous.png" }
        ToolButton { iconSource: "images/go-next.png" }
    }
    Slider {
        anchors.left: row.right
        anchors.leftMargin: 2
        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
    }
}
With Qt Quick Layouts, all items can be added to the same layout:
ToolBar {
    RowLayout {
        anchors.fill: parent
        spacing: 2
        ToolButton { iconSource: "images/go-previous.png" }
        ToolButton { iconSource: "images/go-next.png" }
        Slider { Layout.fillWidth: true }
    }
}
Notice how much shorter the declaration for the Slider element is. Also note that when using Qt Quick Layouts, the spacing only needs to be specified once. Code is reduced from 288 to 172 characters (whitespace excluded), which is a 40% reduction.

Summary

In this example, by using Qt Quick Layouts we got 40% less code, improved readability (not only because the code got shorter, but also because the structure of the code became closer to the structure of the UI).
If you want a resizable UI, you will probably find that Qt Quick Layouts are easier to use than anchors, positioners and manual layouting.

Blog Topics:

Comments