QStateMachine start synchronization
-
Hello,
I am working with Qt 4.7, QtCreator 2.2.1 and MS Visual C++ 2003.
I had a bug in my application that I resolved but I would like your opinion about my bug fix.
I wanted to emit a transition signal just after the State Machine has started like this:
@
machine->start();
emit nextState();
@but this emit was lost and the State Machine stayed in its initial state instead of going to the next state.
I have read the following Qt documentation related to QStateMachine:
- "The State Machine Framework":http://developer.qt.nokia.com/doc/qt-4.7/statemachine-api.html
- "QStateMachine class":http://developer.qt.nokia.com/doc/qt-4.7/qstatemachine.html
This doc notably says: - slot QStateMachine::start() : "Note: A state machine will not run without a running event loop, such as the main application event loop started with QCoreApplication::exec() or QApplication::exec()."
- signal QStateMachine::started() : "This signal is emitted when the state machine has entered its initial state."
Furthermore QStateMachine::start() source code is:
@QMetaObject::invokeMethod(this, "_q_start", Qt::QueuedConnection);@So I tried to synchronize using QStateMachine::started() signal but when I connect to this signal, QStateMachine::isRunning() boolean says false!
So I used the QState::entered() signal of my machine first state and it worked.Is it the good way to fix my bug?
I have created a sample application (based on the TwoWayButton Qt sample) to reproduce my bug and fix it.
Here is the code of my sample:@#include <QtGui>
class QMysteryMachineLabel : public QLabel
{
Q_OBJECT
public:
QMysteryMachineLabel():machine(NULL) {}signals:
void nextState();public slots:
void refresh()
{
if (machine == NULL)
{
// States:
// - State OFF
QState *off = new QState();
off->assignProperty(this, "text", "Off");
off->setObjectName("off");
// - State ON
QState *on = new QState();
on->setObjectName("on");
on->assignProperty(this, "text", "On");// Transitions off->addTransition(this, SIGNAL(nextState()), on); on->addTransition(this, SIGNAL(nextState()), off); // Machine machine = new QStateMachine; machine->addState(off); machine->addState(on); machine->setInitialState(off); // // This connect does not fix the bug! //connect(machine, SIGNAL(started()), this, SLOT(refresh())); // // This connect is the bug fix connect(off, SIGNAL(entered()), this, SLOT(refresh())); // machine->start(); // State should be Off } // When refresh() is called for the first time // and if I don't use connect before starting the machine, // this emit is lost and the state is still Off instead of On emit nextState(); }
protected:
QStateMachine *machine;
};int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;QMysteryMachineLabel labelFSM; QPushButton pushButton("Start FSM"); // Layout QHBoxLayout hbox; hbox.addWidget(&labelFSM); hbox.addWidget(&pushButton); w.setLayout(&hbox); QObject::connect(&pushButton, SIGNAL(clicked()), &labelFSM, SLOT(refresh())); w.show(); return a.exec();
}
#include "main.moc"
@Thanks in advance
Best regards
Pascal