qtqml

Make Hide/Flex Items in QML


Is there any way to replicate this type of hide/flex effect that you can see in this person's question using QML?



I am also using Qt Creator to aid with the UI building. So in the case of my baseline example that I am working with below, I have a button that, when pressed, will reveal a white rectangle that will contain more content inside it in the future.

When this white rectangle appears, the grey rectangle that the white one is inside also lengthens accordingly, basically wrapping it. In the process, the "Some text" is also pushed down, like in the after.png. When the button is pressed again, the white rectangle should disappear and the "Some text" should move back up.

Other than using hide to program part of the functionality, I don't know how to make the objects move around like that. Here's the code that corresponds to the after.png.

import QtQuick 2.4
import QtQuick.Controls 2.12

Item {
    id: item1
    width: 800
    height: 600

    Page {
        anchors.fill: parent

        Rectangle {
            id: bound
            color: "#cad2d7"
            anchors.fill: parent
            anchors.bottomMargin: 0

            Button {
                id: button
                x: 8
                y: 8
                text: qsTr("Button")
            }

            Rectangle {
                id: rectangle
                x: 0
                y: 74
                width: 800
                height: 200
                color: "#ffffff"
            }

            Text {
                id: text1
                x: 14
                y: 293
                text: qsTr("Some text")
                font.pixelSize: 60
            }
        }
    }
}

After:
after.png
Before:
before.png
Note the white that you see in the before.png is just the white backgroud.


Solution

  • It seems like you are looking for something like an accordion design pattern where you can expand to show normally-invisible content. In the scenario you described, a simple approach would be a ColumnLayout inside of a grey base Rectangle, where the visibility of your middle content is toggled. Here is a full stand-alone example:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Layouts 1.12
    
    Window {
        width: 640
        height: 480
        visible: true
    
        Rectangle {
            color: "lightgrey"
            width: parent.width
            height: column.implicitHeight // note this rectangle derives its height from column, and column derives its height from its children's implicitHeight or Layout.prefererredHeight
    
            ColumnLayout {
                id: column
                width: parent.width
                spacing: 0
    
                Button {
                    text: qsTr("Button")
                    onClicked: {
                        middleRectangle.visible = !middleRectangle.visible // toggle middleRectangle visibility
                    }
                }
    
                Rectangle {
                    id: middleRectangle
                    Layout.fillWidth: true
                    Layout.preferredHeight: 100
                    visible: false  // note default is NOT visible
    
                    Text {
                        text: qsTr("New text")
                        font.pixelSize: 60
                    }
                }
    
                Text {
                    text: qsTr("Some text")
                    font.pixelSize: 60
                }
            }
        }
    }
    

    Things to note are: