[Qt-interest] QT SM framework: Ignoring inherited transition w/o causing state transition
Sean Harmer
sean.harmer at maps-technology.com
Fri Mar 26 14:45:08 CET 2010
Hi Mandeep,
On Friday 26 March 2010 13:18:29 Mandeep Sandhu wrote:
> Hi all,
>
> I was going through the Qt docs on how to make a child state ignore an
> event which is valid for its parent state
> (http://doc.qt.nokia.com/4.6/statemachine-api.html#sharing-transitions-by-g
> rouping-states).
>
> The way it's shown is that the child state which wants to ignore the
> event, catches it and simply transitions to itself. This works fine,
> but with a side-effect. It causes the SM to leave the state and enter
> back in. Since I'm using custom states, I do some processing in the
> onEntry/onExit callbacks, they get called even though logically, no
> transition based processing should happen.
>
> Is there a way to "stay" in the same state and not move out and come
> back in? Since I really want to remain in the same state.
Yes, I thought we went through this the other day? Simply make the transition
on the grouping state a guarded transition that checks whether the SM is in
the state from which you wish to ignore the transition.
Using the example from the docs we could do this as follows:
class MyTransition : public QSignalTransition
{
Q_OBJECT
public:
MyTransition( const QList<QAbstractState*> blackList,
QAbstractState* sourceState )
: QSignalTransition( sourceState ), m_blackList( blackList ) {}
bool eventTest( QEvent* e )
{
if ( !QSignalTransition::eventTest( e ) )
return false;
QSet<QAbstractState*> configuration = machine()->configuration();
foreach ( QAbstractState* state, m_blackList )
{
if ( configuration.contains( state ) )
return false;
}
return true;
}
private:
QList<QAbstractState*> m_blackList;
};
Then in the main function instead of calling:
s1->addTransition(quitButton, SIGNAL(clicked()), s2);
we instead use an instance of the above custom transition:
MyTransition* trans
= new MyTransition( ( QList<QAbstractState*>() << s12 ), s1 );
trans->setSenderObject( quitButton );
trans->setSignal( SIGNAL( clicked() ) );
s1->addTransition( trans );
So now, when the quitButton emits the clicked() signal we use the event test
function of our custom transition which simply iterates through its list of
blacklisted states from which we should not transition ans returns true/false
as appropriate.
In this case we return false if the SM is in state s12. And since no
transition happens your processing code in onEntry()/onExit() will not be
called as per your requirements.
NB Note that you can provide a black list of any states. They do not
necessarily have to be children of s1.
Cheers,
Sean
More information about the Qt-interest-old
mailing list