GridView 委托转换不起作用

GridView delegates transitions do not work

我关注QML GridView:

GridView
{
    id: ueProductGridView

    antialiasing: true

    clip: true

    Layout.fillWidth: true
    Layout.fillHeight: true

    cellWidth: 200
    cellHeight: 200

    delegate: Rectangle
    {
        id: test

        width: 192
        height: 192

        color: "red"

        Text
        {
            anchors.fill: parent

            text: index
        }

        transform:
        [
            Rotation
            {
                id: plateRotation

                angle: -90
                axis { x: 0; y: 1; z: 0 }
                origin.x: -200
                origin.y: 0
            }
        ]   // transform

        SequentialAnimation
        {
            id: addAnimation


            PauseAnimation
            {
                duration: Math.random()*2000
            }

            NumberAnimation
            {
                target: plateRotation
                property: "angle"
                to: 0
                duration: 1000
            }
        }

        SequentialAnimation
        {
            id: removeAnimation


            PropertyAction
            {
                target: test
                property: "GridView.delayRemove"
                value: true
            }

            NumberAnimation
            {
                target: test
                property: "scale"
                to: 0
                duration: 1000
            }

            PropertyAction
            {
                target: test
                property: "GridView.delayRemove"
                value: false
            }
        }

        GridView.onAdd:
        {
            addAnimation.start();
        }   // onAdd

        GridView.onRemove:
        {
            removeAnimation.start();
        }   // onRemove
    }   // delegate

    Component.onCompleted:
    {
        model=10;
    }   // onCompleted:
}   // GridView

现在,为什么 delegate 动画 不起作用,即为什么 GridView 是空的 ?有关动画的代码取自 tutorial 并在那里工作。但是,如果我 comment/remove 所有关于动画的代码,delegate 都可以在 GridView 中看到,并且一切正常:

GridView
{
    id: ueProductGridView

    antialiasing: true

    clip: true

    Layout.fillWidth: true
    Layout.fillHeight: true

    cellWidth: 200
    cellHeight: 200

    delegate: Rectangle
    {
        id: test

        width: 192
        height: 192

        color: "red"

        Text
        {
            anchors.fill: parent

            text: index
        }
    }   // delegate

    Component.onCompleted:
    {
        model=10;
    }   // onCompleted:
}   // GridView

与视图中的 insertion/removal 个元素相关联的动画是 Transitions(例如,请参阅 add), between different States and are indeed called ViewTransitions. You should really take a deep look at the documentation 这种类型的页面:它充满了很好的示例,并且描述得非常详细addition/removal 动画应该如何实现。

当您定义 ViewTransition 时,其中引用的任何 属性,如果没有不同的目标,请引用委托 属性。因此,如果你在 GridView:

里面写
add: Transition {
    NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 500 }
    NumberAnimation { property: "scale"; easing.type: Easing.OutBounce; from: 0; to: 1.0; duration: 750 }
}

您是说每次将新委托添加到网格时,其 opacityscale 属性都应该进行动画处理。顶级动画,就像在这种情况下,运行 并行,因此委托被缩放并同时可见。

现在,如果您想为嵌套属性设置动画,例如 Rotation 角的情况,最简单的方法alias 它在里面代表。这样它就可以与任何其他委托 属性 完全相同的方式 处理,从而使代码更清晰、更简单。

应该注意的是,您示例中的动画也不起作用,因为它们与 add Transition 关联。这样的 Transition 而不是 在模型初始化期间使用,而是使用 populate Transition。来自文档:

This property holds the transition to apply to the items that are initially created for a view.

It is applied to all items that are created when:

  • The view is first created
  • The view's model changes
  • The view's model is reset, if the model is a QAbstractItemModel subclass

  • 最后,一个忠告。如果你对元素的添加和删除进行动画处理,尤其是如果动画速度很慢,那么将视图对其他元素所做的 调整 进行动画处理也很重要。以优雅的方式为它们制作动画可以大大改善视觉感受。因此,当您提供 addremove transition 时,还要考虑添加 addDisplaced and a removeDisplaced Transition.

    下面是您的代码的修改版本,它显示了上面讨论的所有要点:

    import QtQuick 2.5
    import QtQuick.Window 2.2
    
    Window {
        id: window
        width: 600
        height: 400
        visible: true
    
        ListModel {
            id: model
             ListElement { code: "0" }
             ListElement { code: "1" }
             ListElement { code: "2" }
             ListElement { code: "3" }
             ListElement { code: "4" }
             ListElement { code: "5" }
        }
    
        GridView {
            id: ueProductGridView
            anchors.fill: parent
            antialiasing: true
    
            clip: true
            cellWidth: 200
            cellHeight: 200
    
            delegate: Rectangle {
                width: 192
                height: 192
    
                color: "red"
                property alias angle: rot.angle     // alias!
                Text {
                    anchors.centerIn: parent
                    text: code
                    font.pixelSize: 30
                }
    
                transform: Rotation {
                    id: rot
                    angle: -90
                    axis { x: 0; y: 1; z: 0 }
                    origin.x: -200
                    origin.y: 0
                }
    
                MouseArea {
                    anchors.fill: parent
                    onClicked: ueProductGridView.model.remove(index)
                }
            }   // delegate
    
            add: Transition {
                NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 500 }        //since is already at 1.0 we should enforce the start from 0
                NumberAnimation { property: "scale"; easing.type: Easing.OutBounce; from: 0; to: 1.0; duration: 750 }
            }
    
            addDisplaced: Transition {
                NumberAnimation { properties: "x,y"; duration: 200; easing.type: Easing.InBack }
            }
    
            remove: Transition {
                NumberAnimation { property: "scale"; from: 1.0; to: 0; duration: 200 }
            }
    
            removeDisplaced: Transition {
                NumberAnimation { properties: "x,y"; duration: 200; easing.type: Easing.OutBack }
            }
    
            populate: Transition {
                NumberAnimation { properties: "angle"; to: 0; duration: 500 }
            }
        }
        Component.onCompleted:{ ueProductGridView.model= model }
    }