QStateMachine animation with QFinalState, bug?



  • I need to make a some geometry animation and catch the moment when we get to final state.

    m_slide_mashine = new QStateMachine();
    m_pSS = new QState();
    m_pFS = new QState();
    QFinalState *fs = new QFinalState();
    m_slide_mashine->addState(m_pSS);
    m_slide_mashine->addState(m_pFS);
    m_slide_mashine->addState(fs);
    m_pSS->addTransition(m_pFS);
    m_pFS->addTransition(fs);
    
    QPropertyAnimation *pAni = new QPropertyAnimation(panel->widget(), "geometry");
    pAni->setEasingCurve(QEasingCurve::InOutCubic);
    pAni->setDuration(DRAG_AND_DROP_CONSTANTS::library_panel_slide_speed);
    m_slide_mashine->addDefaultAnimation(pAni);
    
    connect(m_slide_mashine, &QStateMachine::finished, []() 
    {
        //here we get to final state!
        int n = 0;
        n++;
    });
    

    Remark:
    For m_pSS and m_pFS — I assigned the start and final geometry with a assignProperty() call.

    Now the problem:
    If I use the code above, the animation is not working :-(
    But if I remove QFianl state from code i.e.:

    m_slide_mashine = new QStateMachine();
    m_pSS = new QState();
    m_pFS = new QState();
    m_slide_mashine->addState(m_pSS);
    m_slide_mashine->addState(m_pFS);
    m_pSS->addTransition(m_pFS);
    
    QPropertyAnimation *pAni = new QPropertyAnimation(panel->widget(), "geometry");
    pAni->setEasingCurve(QEasingCurve::InOutCubic);
    pAni->setDuration(DRAG_AND_DROP_CONSTANTS::library_panel_slide_speed);
    m_slide_mashine->addDefaultAnimation(pAni);
    

    , animation work fine, but now I can't catch the moment when it finished.


  • Lifetime Qt Champion

    Hi,

    There seems to be no condition at all to manage the transition to the final state. When should it go there ?



  • Sorry I don't understand your question.
    What "condition" you mean?

    m_pSS - it's initial state (m_slide_mashine->setInitialState(m_pSS);)
    then after assignProperty() I do m_slide_mashine->start();


  • Lifetime Qt Champion

    I mean that with that line for example: m_pSS->addTransition(m_pFS); as soon as your state machine enters the m_pSS state it will go to the m_pFSstate hence your animation not working as you expect. Thus my question, shouldn't you have a condition to transition from m_pSS to m_pFS ? For example a mouse click, number of animation repetition etc.



  • Oh, understand! :-)
    No condition is not required.
    And sorry for my mistake in first post, when i said "animation is not working" I mean that after call m_slide_mashine->start() we immediately go from m_pSS -> m_pFS -> QFinalState (i.e. without duration) , but when I do not use QFinalState animation work as expected (with duration as I set in pAni->setDuration() ).


  • Lifetime Qt Champion

    It happens precisely because you didn't put any condition for the transition between the two states. If you take a look at the Simple State Machine example, the condition to change state is a mouse click.

    So you have to determine what should trigger the transition between m_pSS and m_pFS and use the adequate QAbstractTransition subclass.



  • Sorry but I don't understand again.
    Why I need "condition" when API allow do that without it?
    And why animation is broken only when I try to use QFinalState?


  • Lifetime Qt Champion

    The animation is not broken.

    Like I already wrote: m_pSS->addTransition(m_pFS); means that as soon as your state machine enters the m_pSS state it will transition to m_pFSthus the state machine will stop since it's a final state.



  • I understand.
    Thank you!


  • Lifetime Qt Champion

    You're welcome !

    So you could make it work the way you wanted ?



  • Yes. Thank you!


  • Lifetime Qt Champion

    Great !

    You'r welcome !

    Since you have it working now, please mark the thread as solved using the "Topic Tools" button so that other forum users may know a solution has been found :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.