12

I'm trying to implement a state-machine in Qt (C++). How can I check the current state of the QStateMachine? I couldn't find a method in the documentation.

thx

Verbeia
  • 4,400
  • 2
  • 23
  • 44
tbienias
  • 629
  • 2
  • 7
  • 15

4 Answers4

15

have you tried QStateMachine::configuration() ?

refer http://www.qtcentre.org/threads/42085-How-to-get-the-current-state-of-QStateMachine

Excerpt from the above url:

// QStateMachine::configuration() gives you the current states.

while(stateMachine->configuration().contains(s2))
{
     //do something
}
menjaraz
  • 7,551
  • 4
  • 41
  • 81
Hemant Metalia
  • 29,730
  • 18
  • 72
  • 91
  • Well yes, but when I tried it none of the states I had added were there. I do not have my own QState classes, just regular QStates. – ExpatEgghead Feb 01 '12 at 07:54
  • As part of my application, I need to send to another machine the current state of the application. It does not seem sensible to hunt through a Set for this. Perhaps my mistake was not creating a derived class for all my States. – ExpatEgghead Feb 02 '12 at 06:59
  • @ExpatEgghead: I believe that you may receive more attention if you can provide minimal an complete code illustrating your issue. – menjaraz Feb 02 '12 at 08:51
8

You can assign the property to the QStateMachine itself.

// QState        m_State1;
// QState        m_State2;
// QStateMachine m_Machine;

m_State1.assignProperty(m_Label,    "visible", false);
m_State1.assignProperty(&m_Machine, "state",   1);

m_State2.assignProperty(m_Label,     "visible", true);
m_State2.assignProperty(&m_Machine,  "state",   2);

Then, the current state can be read from dynamic property.

qDebug() << m_Machine.property("state");
3

From Qt 5.7 Documentation

QSet QStateMachine::configuration() const

Returns the maximal consistent set of states (including parallel and final states) that this state machine is currently in. If a state s is in the configuration, it is always the case that the parent of s is also in c. Note, however, that the machine itself is not an explicit member of the configuration.

Example usage:

bool IsInState(QStateMachine& aMachine, QAbstractState* aState) const
{
   if (aMachine_.configuration().contains(aState)) return true;
   return false
}
kay
  • 198
  • 1
  • 6
2

I realize I'm coming in late, but hopefully this answer helps anyone else who stumbles across this.

You mentioned above that you already tried to use configuration(), but none of your states were there--this is because start() is asynchronous.

So, assuming you called configuration() immediately after calling start(), it makes sense that your states weren't there yet. You can get the functionality you want by using the started() signal of the QStateMachine class. Check it out:

stateMachine->setInitialState(someState);
stateMachine->start();
connect(stateMachine, SIGNAL(started()), this, SLOT(ReceiveStateMachineStarted()));

Then, for your ReceiveStateMachineStarted() slot, you could do something like this:

void MyClass::ReceiveStateMachineStarted() {
    QSet<QAbstractState*> stateSet = stateMachine->configuration();
    qDebug() << stateSet;
}

When your state machine enters its initial state, it will emit the start() signal. The slot you've written will hear that and print the config. For more on this, see the following Qt documentation:

http://doc.qt.io/qt-5/qstatemachine.html#started

Sam F
  • 21
  • 3