Search code examples
animationqmlqtquick2qt-quickqtquickcontrols

Animation on expand/collapse of Qt Quick TreeView


I have asked this question over at the Qt forums (link), but received no response, and a similar question over there has gone unanswered for 3 months... so here I am.

I am trying to animate the expand and collapse of a TreeView in QML. I have an animation in a flickable elsewhere in my applicaiton where the height of a child object in the flickable is animated to emulate "expanding" and I need the expand/collapse of the TreeView to be the same (or at least similar).

I tried adding an animation on the height of my row inside my rowDelegate which had no effect:

Behavior on height {
  NumberAnimation {
    duration: 250
    easing.type: Easing.InOutQuad
}

Looking at the TreeView implementation done by Gabriel de Dietrich and Caroline Chao packaged with Qt (documentation here), it seems that they perform an insert of the child data into the private "__listView" when the parent is expanded, and a remove when it's collapsed.

After some research I was able to find information on view transitions and a few tips from a stackoverflow answer regarding animating new items in a table.

Armed with these tips I was able hack around in the private properties of the TreeView to get a pretty crappy expand animation...

TreeView {
    id: tree
    model: myModel
    Transition {
        id: treeTransitionAnimation
        NumberAnimation { properties: "y"; duration: 300 }
    }

    Component.onCompleted: {
        if(this.__listView) {
            this.__listView.add  = treeTransitionAnimation
            this.__listView.remove  = treeTransitionAnimation
            //doesn't actually work on remove. The child items in the tree just disappear.
        }
        else {
            console.log("Something bad happened. Darn.")
        }
    }
...

This slides the new items in from the top of the tree when they are expanded (inserted)... but is not what I need. I know it's bad practice to use the private properties of these QML objects, but I'll take anything that works.

Also note, the above doesn't actually even work on remove.

Substituting "height" for "y" in the number animation above also does not work.

The Qt class used for trees has a simple boolean property for animating the tree expansion and collapse, but the TreeView has no such property.

Does anyone out there know of a way to accomplish this animation?

Thanks in advance for any advice!

EDIT I have also tried adding ListView.onAdd and ListView.onRemove handlers in the rowDelegate and itemDelegate to no avail... see example below:

rowDelegate:     Rectangle {
        id: rowDelegateItem
        height: 100

        SequentialAnimation {
            id: collapseAnimation
            running: false
            PropertyAction { target: rowDelegateItem; property: "ListView.delayRemove"; value: true }
            NumberAnimation { target: rowDelegateItem; properties: "height"; to: 0.0; duration: 250 }
            PropertyAction { target: rowDelegateItem; property: "ListView.delayRemove"; value: false }
        }

        SequentialAnimation {
            id: addAnimation
            running: false
            PropertyAction { target: rowDelegateItem; property: "height"; value: 0 }
            NumberAnimation { target: rowDelegateItem; properties: "height"; to: 100; duration: 250 }
        }

        ListView.onRemove: {
            console.log("onRemove");
            collapseAnimation.start();
        }

        ListView.onAdd: {
            console.log("onAdd");
            addAnimation.start();
        }

But the "onAdd" and "onRemove" log outputs are never even printed.


Solution

  • I was able to improve my expand animation, however the (almost) final answer to the question from Qt is that a collapse animation is not possible without editing the Qt source code directly (and maybe not even then...?). For many this is not a viable option and therefore not an answer.

    This problem will exist until after the new Qt Controls version is released and updated with a brand new implementation of TreeView https://bugreports.qt.io/browse/QTBUG-56490.
    FYI: That link states "It's way too late for 5.8" so I believe it's safe to assume this will come after 5.8.

    I am in the process of discussing edits to the Qt source code with Qt support, but as an answer to the question as stated above, the answer is it cannot be done in current versions of Qt. (the current supported release at the time of this answer is 5.7)