1

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;
    }
}
4

1 に答える 1

2

私はこれがそれをするだろうと思います:

if(viewAnimation)
{
    // jump to end of animation, without any further knowledge of it:
    viewAnimation->targetObject()->setProperty(viewAnimation->propertyName(),
                                               viewAnimation->endValue());
    cancelViewAnimation();
}
于 2012-07-14T12:41:03.503 に答える