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:

    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&#40;&#41;;
    

    }

    #include "main.moc"
    @

    Thanks in advance
    Best regards
    Pascal


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.