Results 1 to 6 of 6

Thread: Questions related to QStateMachine

  1. #1
    Join Date
    Dec 2010
    Location
    Ottawa, On, Canada
    Posts
    11
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Questions related to QStateMachine

    Good afternoon,

    I am doing some refactoring toward using a QStateMachine for an existing application. So far that process is going well but I do have a few questions.

    a. How can I define a QHistoryState state that applies to the entire state machine. For example, the operator can elects to close the application at any time, but our SW requirements stipulate that a confirmation is required. I was thinking of using a history state (to be used as an interrupt), request the confirmation from the operator, and then restore to the current state when the operator declines to close the application. Or should I simply leave the handling of the 'Close Application' signal outside the state machine and post the appropriate event when the application is to be closed.

    b. I get a compilation error when trying to declare a transition based on a signal emitted from an object ScriptThread (which is derived from QThread).

    error: no matching function for call to ‘QState::addTransition(ScriptThread*&, const char [12], QState*&)’
    acquisitionState->addTransition( m_scriptThread, SIGNAL( finished()), acquisitionCompletedState);
    However, the original code had a 'connect' using the same signal as the one listed above. This code compiles and executes properly.
    Qt Code:
    1. connect( m_scriptThread, SIGNAL( finished()), this, SLOT( scriptFinished()), Qt::QueuedConnection);
    To copy to clipboard, switch view to plain text mode 
    As I said, ScriptThread is derived from QThread. I can rework around this using postEvent() in a SLOT handling the finished() signal. But I am curious about this compilation error.

    Thanks in advance
    Daniel

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Questions related to QStateMachine

    a. How can I define a QHistoryState state that applies to the entire state machine. For example, the operator can elects to close the application at any time, but our SW requirements stipulate that a confirmation is required. I was thinking of using a history state (to be used as an interrupt), request the confirmation from the operator, and then restore to the current state when the operator declines to close the application. Or should I simply leave the handling of the 'Close Application' signal outside the state machine and post the appropriate event when the application is to be closed.
    QHistoryState is not a solution to save the state when application closes.


    I get a compilation error when trying to declare a transition based on a signal emitted from an object ScriptThread (which is derived from QThread).

    error: no matching function for call to ‘QState::addTransition(ScriptThread*&, const char [12], QState*&)’
    acquisitionState->addTransition( m_scriptThread, SIGNAL( finished()), acquisitionCompletedState);

    However, the original code had a 'connect' using the same signal as the one listed above. This code compiles and executes properly.
    Try to clean all and rebuild, that should slove the problem.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  3. #3
    Join Date
    Dec 2010
    Location
    Ottawa, On, Canada
    Posts
    11
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Questions related to QStateMachine

    Thanks for the reply,

    Regarding the compilation error, clean all and rebuild did not resolve the issues. I get the same error whether the code is compiled using Qt 4.8.1 or Qt 4.6. So the investigation continues.

    The 'Close application' was used as an example. As I said, our SW requirements specify that a confirmation is required from the operator before actually closing the application. Say the operator confirms closing the application, the state machine would enter a QFinalState. However, a negative response would return the application to its current state. Hence the idea to use a QHistoryState approach.

    But in general, I wanted to know how to implement a QHistoryState that could be used across the entire state machine. The examples I saw are defining QHistoryState "as a child of the state for which we wish to record the current child state" (from QStateMachine framework). The state machine I am working on has 4 parent states (identification, setup, acquisition, review). Do I need to define a QHistoryState for each parent state although the code associated to the history state would be the same? As my original question, how to implement a QHistoryState that applies to the entire state machine?

    I guess this confirmation from the operator can be viewed differently. A QMessageBox (with Yes/No buttons) is used to handle the confirmation. QSignalTransition could be used to set the transition to the correct state, but then the current child state must be recorded somehow before the QMessageBox is used.

    Daniel

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Questions related to QStateMachine

    I think what you would need to do is create one top level state that contains your current top level states, lets call that runningState and a sibling top level state called "confirmQuit" state.

    Then you create a QHIstoryState as a child of runningState (as a sibling of your previous top level states) and a transition from confirmQuit to that history state which is triggered by "do not quit".

    Cheers,
    _

  5. The following user says thank you to anda_skoa for this useful post:

    ottawaDan (14th February 2013)

  6. #5
    Join Date
    Dec 2010
    Location
    Ottawa, On, Canada
    Posts
    11
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Questions related to QStateMachine

    The last response to my post read:
    I think what you would need to do is create one top level state that contains your current top level states, lets call that runningState and a sibling top level state called "confirmQuit" state.

    Then you create a QHIstoryState as a child of runningState (as a sibling of your previous top level states) and a transition from confirmQuit to that history state which is triggered by "do not quit"
    I modified the state machine, creating a top level state (applicationParentState), and included the declaration of the portion of the state machine defined as parallel states (identified as setup state in the state machine I am working on; 4 parent states (identification, setup, acquisition, review))

    Qt Code:
    1. applicationParentState = new QState();
    2.  
    3. imagingSetupState = new QState( QState::ParallelStates, applicationParentState);
    4. QState* haloReflectionSetup = new QState( imagingSetupState);
    5. QState* patientAlignment = new QState( imagingSetupState);
    6.  
    7. QState* phakicStateGroup = new QState( haloReflectionSetup);
    8. QState* initPhakicState = new QState( phakicStateGroup);
    9. QState* phakicState = new QState( phakicStateGroup);
    10. QState* haloReflectionAlignment = new QState( phakicStateGroup);
    11.  
    12. QState* pseudoPhakicStateGroup = new QState( haloReflectionSetup);
    13. QState* initPseudoPhakicState = new QState( pseudoPhakicStateGroup);
    14. QState* pseudoPhakicState = new QState( pseudoPhakicStateGroup);
    15. QState* iolAlignLeftState = new QState( pseudoPhakicStateGroup);
    16. QState* iolAlignRightState = new QState( pseudoPhakicStateGroup);
    17.  
    18. QState* alignmentIdle = new QState( patientAlignment);
    19. QState* pupilSetupState = new QState( patientAlignment);
    20. QState* focusOnRetinaState = new QState( patientAlignment);
    21.  
    22. patientAlignment->setInitialState( alignmentIdle);
    23. phakicStateGroup->setInitialState( initPhakicState);
    24. pseudoPhakicStateGroup->setInitialState( initPseudoPhakicState);
    25. haloReflectionSetup->setInitialState( phakicStateGroup);
    26.  
    27. stateMachine.addState( applicationParentState);
    28.  
    29. QHistoryState* applicationParentStateHistory = new QHistoryState( QHistoryState::DeepHistory, applicationParentState);
    30.  
    31. QState* confirmAppClosingState = new QState();
    32. confirmAppClosingState->addTransition( applicationParentStateHistory);
    33. applicationParentState->addTransition( actionClose, SIGNAL( triggered()), confirmAppClosingState);
    34. QObject::connect( confirmAppClosingState, SIGNAL( entered()), this, SLOT( confirmClosingApplication()));
    35. stateMachine.addState( confirmAppClosingState);
    36.  
    37. closingApplicationState = new QFinalState( );
    38. ...
    To copy to clipboard, switch view to plain text mode 
    Testing the confirmation code works well when in the identification state. However, if confirmation is executed while in any child state declared under imagingSetupState (say pupilSetupState), the execution will go thru all the state transitions when returning to pupilSetupState, and do the same in the haloReflectionSetup; ie walk thru every state transitions and execute every method assigned with entered() and exited() signal for each state.

    I am looking at changing the definition of the state machine to eliminate the QState::ParallelStates but I am afraid that the number of transitions will become unmanageable as I know that some expansion is coming soon.

    Would it be preferable to define a QHistoryState locally for each the haloReflectionSetup and patientAlignment parent states which would handle the confirmation on closing the application.

    I guess I could leave the confirmation completely out of the state machine definition and only define a transition to the QFinalState.
    But I still would like to know if it is possible/recommended to use a QHistoryState as a sibling of a parent state with the QState::ParallelStates attributes?

    Thanks
    Daniel

  7. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Questions related to QStateMachine

    Maybe this behavior is triggered by the deep history.

    You could try having a history state for each state group and using the history state as the initial state. I would expect this to restore each entered substate, kind of like a restore cascade.

    Cheers,
    _

Similar Threads

  1. QT related interview questions
    By gulhk in forum General Discussion
    Replies: 7
    Last Post: 7th October 2015, 11:00
  2. GNU LGPL and other related questions
    By mtnbiker66 in forum Qt Programming
    Replies: 6
    Last Post: 27th June 2012, 23:27
  3. Thread related questions
    By Cruz in forum Qt Programming
    Replies: 11
    Last Post: 22nd February 2011, 10:57
  4. QT related interview questions
    By gulhk in forum Qt Programming
    Replies: 2
    Last Post: 6th February 2011, 10:38
  5. Some questions related to Qt tutorials
    By jamadagni in forum Newbie
    Replies: 2
    Last Post: 17th March 2007, 10:51

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.