为自定义项目添加过渡

Adding transitions for custom Item

我有一个像这样的简单 QML 代码:

GridView {
    id: viewId

    anchors.fill: parent

    delegate: delegateId
    cellWidth: 100
    cellHeight: 100    
}

Component {
    id: delegateId

    Rectangle {
        id: rectId

        width:  100
        height: 100

        MyCystomItem {
            id: imageId
            anchors.centerIn: parent
            height: parent.height
            width:  parent.width

            myCustomProperty: myCustomRole                
        }
    }
}

在委托中,我使用 MyCustomItem,它是在我的项目的 C++ 端定义的。 当第一次调用 MyCustomItem::paint() 时,我绘制了一些 'wait' 指标, 并使用传递给 myCustomProperty 的值,我开始在线程上进行一些计算。 计算完成后,我调用 MyCustomItem::update() 并绘制计算结果。

我想尝试 QtQuick 的过渡,让网格更生动,所以我虽然 关于在 'wait' 和“最终结果”状态之间添加一些转换。哪一个并不重要, 问题是我不知道这样做的正确方法是什么。 我想避免在我的 C++ 代码中进行任何基于计时器的尝试。我想放置过渡 直接在 qml 文件中,这样我就可以轻松地试验各种效果。

下一步是在 'wait' 状态处于活动状态时向项目添加转换。 对此最类似 qml 的方法是什么?

尚不完全清楚您想要制作动画的具体内容。但我会尝试给出一些想法

选项 1

您可以使用 waiting(或更好的 working)和 done 等属性公开自定义项目的内部状态。在 QML 中,您可以绑定到 State objects and Transition objects:

中的这些属性
MyCystomItem {
    id: imageId
    anchors.centerIn: parent
    height: parent.height
    width:  parent.width

    myCustomProperty: myCustomRole

    states: [
        State {
            name: "working"
            when: imageId.working && !imageId.done
            //you could set properties
        },
        State {
            name: "done"
            when: !imageId.working && imageId.done
            //you could set properties
        }
    ],
    transitions: [
        Transition {
            from: "*"
            to: "working" //here goes the name from the state
            NumberAnimation {
                properties: "x,y";
                easing.type: Easing.InOutQuad;
                duration: 200;
            }                
        }
    ]      
}

选项 2

根据计算内容,您可以添加一个或多个表示结果的属性并使用 Behavior 对象。既然你 id 了自定义项目 imageId,我认为你对这个选项并不真正感兴趣,只是为了完整而把它放在这里。

另请注意,此选项暴露了一些混合职责的问题 (see wikipedia);计算是在与表示相同的 class 中完成的。所以在下面的代码中,我假设 MyCustomItem 只进行计算(一旦实例化)

Rectangle {
    id: tempView
    anchors.centerIn: parent
    height: parent.height
    width:  parent.width

    color: imageId.working ? "transparent" 
                           : imageId.temperature < 20 ? "blue" : "red"
    Behavior on color { ColorAnimation { duration: 500 } }

    MyCystomItem {
        id: imageId
    }
}

选项 3

最后,您可以使用 ProgressBar 使网格更加生动。为此,需要了解计算的距离,当然还要公开该值

import QtQuick.Controls 2.3

MyCystomItem {
    id: imageId
    anchors.centerIn: parent
    height: parent.height
    width:  parent.width


    ProgressBar {
       anchors.left: parent.left
       anchors.right: parent.right
       anchors.bottom: parent.bottom
       value: imageId.progress
       visible: imageId.progress < 100
    }
}

结论

我认为这个答案中最有价值的部分是使用 Q_PROPERTY 将您的内部计算状态暴露给 QML 端。因为您只能控制可见的内容。