Qt World Summit: Submit your Presentation

QScxmlStateMachine targetless transition

  • Hi

    I am experimenting with the QScxmlStateMachine class. Is it possible to add a targetless transition to states in my state machine? How do I do it?

    My use case is, I have a C++ app, with 2 states, "normalmode" and "crazymode". I have an event "received_packet_blah", I want to handle this event differently in my two states. I don't want this event to cause a state change.

    I can see how to do this with QStateMachine (http://doc.qt.io/qt-5/statemachine-api.html), which has a good description, but not for QScxmlStateMachines. I don't really understand the relationship between QStateMachines and QScxmlStateMachines - are they totally unrelated?

    I suppose I could call QScxmlStateMachine::connectToEvent("received_packet_blah", SLOT(rx_blah));, and inside rx_blah() I could find out whether I was in crazymode or normalmode, and call the relevant event handler, but it seems clumsy, and I get the feeling I am trying to do this the wrong way.


  • Lifetime Qt Champion


    Yes both are unrelated, QStateMachine was created a long time before QScxmlStateMachine and they do not share implementation nor logic as the later is based on the SCXML Specification.

    Can you show how you defined your state machine ?

  • @SGaist, I don't have sufficient privileges to attach files, so I have copy and pasted below:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QScxmlStateMachine>
    #include "eventhandler.h"
    #include "hsm.h"

    int main(int argc, char *argv[])
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    if (engine.rootObjects().isEmpty())
        return -1;
    EventHandler eventhandler;
    hsm statemachine;
    bool retval = static_cast<bool>(statemachine.connectToState("normal_mode", &eventhandler, SLOT(On_enter_state_normal_mode(bool))));
    retval &= static_cast<bool>(statemachine.connectToState("crazy_mode", &eventhandler, SLOT(On_enter_state_crazy_mode(bool))));
    retval &= static_cast<bool>(statemachine.connectToEvent("rx_packet_blah", &eventhandler, SLOT(On_event_rx_packet_blah())));
    return app.exec();


    <?xml version="1.0" encoding="UTF-8"?>
    <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="hsm" qt:editorversion="4.4.1" xmlns:qt="http://www.qt.io/2015/02/scxml-ext">
    <state id="wrapper">
    <qt:editorinfo scenegeometry="172.33;289.58;52.52;239.58;711.81;286" geometry="172.33;289.58;-119.81;-50;711.81;286"/>
    <state id="normal_mode">
    <qt:editorinfo scenegeometry="259;398.15;199;317.02;120;131.13" geometry="86.67;108.57;-60;-81.13;120;131.13"/>
    <transition type="external" event="enter_crazy_mode" target="crazy_mode"/>
    <state id="crazy_mode">
    <qt:editorinfo scenegeometry="525.13;382.58;465.13;332.58;120;100" geometry="352.80;93;-60;-50;120;100"/>
    <transition type="external" event="enter_normal_mode" target="normal_mode">
    <qt:editorinfo endTargetFactors="75.48;76.19"/>

  • Lifetime Qt Champion

    The QtScxml Sudoku example mentions a target less transition so it might give you the information you are missing.

  • @SGaist , thank you very much. This is exactly what I was looking for.

  • Lifetime Qt Champion

    @d_h_mcinnes then please mark this topic as SOLVED. thanks

Log in to reply