Important: Please read the Qt Code of Conduct -

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:
    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:

    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
    QMysteryMachineLabel():machine(NULL) {}

    void nextState();

    public slots:
    void refresh()
    if (machine == NULL)
    // States:
    // - State OFF
    QState *off = new QState();
    off->assignProperty(this, "text", "Off");
    // - State ON
    QState *on = new QState();
    on->assignProperty(this, "text", "On");

            // Transitions
            off->addTransition(this, SIGNAL(nextState()), on);
            on->addTransition(this, SIGNAL(nextState()), off);
            // Machine
            machine = new QStateMachine;
            // 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();

    QStateMachine *machine;

    int main(int argc, char *argv[])
    QApplication a(argc, argv);
    QWidget w;

    QMysteryMachineLabel labelFSM;
    QPushButton pushButton("Start FSM");
    // Layout
    QHBoxLayout hbox;
    QObject::connect(&pushButton, SIGNAL(clicked()), &labelFSM, SLOT(refresh()));;
    return a.exec&#40;&#41;;


    #include "main.moc"

    Thanks in advance
    Best regards

Log in to reply