QT – Animating Layout.preferredWidh / Layout.preferredHeight

I just searched the web on how to animate a change in the Layout.preferredWidh / Layout.preferredHeight properties without finding anything useful.

It’s not that hard but maybe could save some minutes to others, so here my solution:

Behavior on Layout.preferredWidth  {
    NumberAnimation
        { duration: 150; easing.type: Easing.InOutQuad }
    }

Just add this behavior to your element to have a nice animation during any change to the Layout.preferredWidth  property.

An example? I was in need to collapse a side panel in a simple layout, here you can see the layout, obtained using a GridLayout, composed by a side panel and the main content. Clicking the button the side panel collapse with a nice animation, it also hide with another animation its content.

And here, the full code for the example. Enjoy

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Window {
        visible: true
        width: 800
        height: 500
        title: qsTr("Collapsable panel")

    Rectangle {
        anchors.fill: parent
        color: "#ffffff"
    }

    GridLayout {
        id : grid
        anchors.fill: parent
        rows    : 12
        columns : 12
        property double colMulti : grid.width / grid.columns
        property double rowMulti : grid.height / grid.rows
        function prefWidth(item){
            return colMulti * item.Layout.columnSpan
        }
        function prefHeight(item){
            return rowMulti * item.Layout.rowSpan
        }

        Rectangle {
            id: colsx
            color: "#000000"
            Layout.rowSpan   : 12
            Layout.columnSpan: 4
            Layout.preferredWidth  : grid.prefWidth(this)
            Layout.preferredHeight : grid.prefHeight(this)

            Behavior on Layout.preferredWidth  {
              NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
            }

            ColumnLayout {
                id: sxlay
                width: parent.width

                Behavior on visible  {
                  NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
                }

                anchors.centerIn: parent
                Label {
                    text: "Side Panel"
                    height: 40
                    Layout.alignment: Layout.Center
                    color: "white"
                    font.pointSize: 22
                }

                Button {
                    text: "Collapse"
                    Layout.alignment: Layout.Center
                    onClicked:  {
                            colsx.Layout.preferredWidth  = 0
                            coldx.Layout.preferredWidth = grid.width;
                            sxlay.visible = false;
                    }
                }
            }
        }

        Rectangle {
            id: coldx

            color: "#000000"
            Layout.rowSpan   : 12
            Layout.columnSpan: 8
            Layout.preferredWidth  : grid.width-48
            Layout.preferredHeight : grid.prefHeight(this)

            ColumnLayout {
                width: parent.width
                anchors.centerIn: parent
                Label {
                    text: "Main Content"
                    height: 40
                    Layout.alignment: Layout.Center
                    color: "white"
                    font.pointSize: 22
                }
            }
              }
         }
}