Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Collapsable menu with responsive height
Qt 6.12 LTS is out! See what's new in the release blog

Collapsable menu with responsive height

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 282 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Guillaume Lacroix
    wrote on last edited by
    #1

    I've got a simple collapsable menu, that contains a title for the menu ("Hair color"), and 2 items within it ("Blond" and "Brown"). I also have an animation that displays/hides the different items within it in a linear fade in/fade out of 500ms. That works fine as a visual, however I cannot figure out how to make the menu itself take the height during the animation: at any given time during the 500ms animation, i would like whatever is below the menu (a line in this example) to be located at the position of the lowest displayed item within the menu. What I get instead is that as soon as the animation starts for opening, the menu takes the whole space of the items (even the ones that aren't displayed yet). Same when hiding.

    Below is the code that I currently have:

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.15
    
    Item {
        property bool expanded: false
        property int filterWidth: 400
    
        id: root
        width: filterWidth
        height: columnFilter.implicitHeight
    
        ColumnLayout {
            id: columnFilter
            width: parent.width
    
            RowLayout {
                id: row
                height: implicitHeight
                Layout.margins: 10
                width: parent.width - Layout.leftMargin - Layout.rightMargin
                spacing: 10
    
                Text {
                    id: text1
                    text: qsTr("Hair color")
                    font.pixelSize: 16
                }
    
                Item {
                    Layout.fillWidth: true
                }
    
                Image {
                    id: expandIcon
                    width: 20
                    height: 20
                    sourceSize: Qt.size(width, height)
                    source: "./Up-black.svg"
                    fillMode: Image.PreserveAspectFit
                    rotation: 180
                }
            }
    
            Column {
                id: filterValues
                spacing: 10
                height: 0
                clip: true
                Layout.leftMargin: 12
                visible: height > 0
    
                onHeightChanged:  {
                    console.log("bottom col " + (y + height))
                }
    
                Text {
                    id: blond
                    text: qsTr("Blond")
                    font.pixelSize: 16
                    clip: true
                }
    
                Text {
                    id: brown
                    Layout.margins: 12
                    text: qsTr("Brown")
                    font.pixelSize: 16
                    clip: true
                }
            }
    
            Rectangle {
                id: line1
                width: row.width
                height: 2
                color: "black"
            }
    
            MouseArea {
                id: filterTitleMouseArea
                anchors.fill: row
                enabled: true
                onClicked: expanded = !expanded
            }
        }
    
        states: [
            State {
                name: "Expanded"
                when: root.expanded
    
                PropertyChanges {
                    target: expandIcon
                    rotation: 0
                }
                PropertyChanges {
                    target: filterValues
                    height: implicitHeight
                }
            }
        ]
    
        transitions: [
            Transition {
                id: transition1
                ParallelAnimation {
                    PropertyAnimation {
                        target: expandIcon
                        property: "rotation"
                        duration: 200
                    }
                    PropertyAnimation {
                        target: filterValues
                        property: "height"
                        duration: 500
                    }
                }
                to: "*"
                from: "*"
            }
        ]
    
    }
    

    What I would like is something that looks like this:

    Rectangle {
               id: line1
               width: row.width
               height: 2
               color: "black"
               top: filterValues.y + filterValues.height
           }
    

    Which kinda works, but doesn't take into account the margins/padding of the filterValues column, and seems like a hack honestly. Is there a way to do that natively with the QML framework?
    For reference, I'm using Qt 5.15.13.

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt
    • Unsolved