1
我使用QPropertyAnimation爲用戶輸入設置動畫以在小部件中導航。也就是說,我使用它來平滑使用鼠標滾輪進行縮放。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 %
我恨APPLICAT在動畫結束之前無法進行更多用戶輸入的離子,因此我主要討厭流暢的動畫。所以我想要的是:當用戶給出另一個用戶輸入並且當前有一個動畫正在運行時,通過跳到這個動畫的末尾來「跳過」這個動畫。
最簡單的解決方案是將剛纔的動畫的結束值用於新動畫的開始值,但我想抽象當前正在執行的動畫的「類型」它不一定是縮放動畫,但也可以是滾動,平移,任何動畫。
那麼,有沒有一種可能性,沒有動畫的進一步瞭解(我只有一個指向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;
}
}