QPropertyAnimation:立即跳到动画结束?

时间:2012-07-14 12:27:30

标签: c++ qt animation

我使用QPropertyAnimation动画用户输入以在窗口小部件中导航。也就是说,我用它来平滑使用鼠标滚轮进行缩放。

目前,当用户提供新输入(旋转鼠标滚轮)时,当前动画将被取消并开始新动画,从我的缩放属性的当前值开始。

例如,如果放大操作将视图缩放了2倍,我们可以想象以下场景:

   User input         |  Zoom before the animation  |  Animation's end value
----------------------+-----------------------------+--------------------------
   Mouse wheel up     |                      100 %  |                  200 %
   (wait)             |                             |
   Mouse wheel up     |                      200 %  |                  400 %
   (wait)             |                             |
   Mouse wheel up     |                      400 %  |                  800 %

但是如果用户不等待动画完成:

   User input         |  Zoom before the animation  |  Animation's end value
----------------------+-----------------------------+--------------------------
   Mouse wheel up     |                      100 %  |                  200 %
   Mouse wheel up     |                      110 %  |                  220 %
   Mouse wheel up     |                      120 %  |                  240 %

我想要的(再次,用户不会等待):

   User input         |  Zoom before the animation  |  Animation's end value
----------------------+-----------------------------+--------------------------
   Mouse wheel up     |                      100 %  |                  200 %
   Mouse wheel up     |  immediately jump to 200 %  |                  400 %
   Mouse wheel up     |  immediately jump to 400 %  |                  800 %

我讨厌在动画结束之前无法再进行用户输入的应用程序,因此我大多讨厌平滑的动画。所以我想要的是:当用户提供另一个用户输入并且当前正在运行动画时,跳过这个动画的结尾“跳过”这个动画。

最简单的解决方案是只使用前一个动画的结束值作为新动画的起始值,但我想抽象出当前执行的动画的“类型”;它不一定是缩放动画,但也可以是滚动,平移,无论动画。

有没有可能,没有进一步的动画知识(我只有一个指向QPropertyAnimation的指针),使立即跳到最后强>

目前,我的代码如下所示:

class View : ...
{ 
    // Property I want to animate using the mouse wheel
    Q_PROPERTY(qreal scale READ currentScale WRITE setScale)
    ...
private:
    // Pointer to the animation, which can also be another animation!
    QPropertyAnimation *viewAnimation;
}
void View::wheelEvent(QWheelEvent *e)
{
    qreal scaleDelta = pow(1.002, e->delta());
    qreal newScale = currentScale() * scaleDelta;

    if(viewAnimation)
    {
        // --- CODE SHOULD BE INSERTED HERE ---
        // --- Jump to end of viewAnimation ---
        // --- rather than canceling it     ---
        cancelViewAnimation();
    }
    viewAnimation = new QPropertyAnimation(this, "scale", this);
    viewAnimation->setStartValue(currentScale());
    viewAnimation->setEndValue(newScale);
    viewAnimation->setDuration(100);
    connect(viewAnimation, SIGNAL(finished()), SLOT(cancelViewAnimation()));
    viewAnimation->start();
}

void View::cancelViewAnimation()
{
    if(viewAnimation)
    {
        viewAnimation->stop();
        viewAnimation->deleteLater();
        viewAnimation = NULL;
    }
}

1 个答案:

答案 0 :(得分:2)

我认为这样做会:

if(viewAnimation)
{
    // jump to end of animation, without any further knowledge of it:
    viewAnimation->targetObject()->setProperty(viewAnimation->propertyName(),
                                               viewAnimation->endValue());
    cancelViewAnimation();
}