State Machines in Qt 6.2

State machines are abstract computational machines that can be in only one of their finite number of states at any given time. They can change from one state to another in response to inputs. State machines can be defined by the list of their states, their initial state and the inputs that trigger the state transitions. State machines are usually visualized by state charts:

A state chart from the Sub-Attaq Qt State Machine Framework example. 

Qt 5 has two components which support creating and working with state machines: the Qt State Machine Framework and Qt SCXML.

Qt State Machine Framework

The Qt State Machine Framework provides classes for creating and executing state machines. States and transitions can be created and connected both programmatically and from QML. The framework integrates tightly with Qt’s meta-object system: transitions between states can be triggered by signals, and states can be configured to set properties and invoke methods on QObjects. The framework supports hierarchical states, parallel states, history states and it is also integrated with the Animation API in Qt to allow automatically animating properties when they are assigned to states. QStateMachines can also be nested to break down big state machines to smaller functional units for clarity or reuse.

Qt SCXML

SCXML stands for State Chart XML. It is a standardized XML based markup language that is able to describe complex state machines. The Qt SCXML module creates classes from SCXML files that can be embedded in Qt applications. Parts of the application logic can be replaced with an encapsulated SCXML file. This enables creating a clear division between the application logic and the user interface implementation by using Qt Quick or Qt Widgets. In Qt SCXML, state machines are read from separate SCXML files and integrated to Qt applications by instantiating the QScxmlStateMachine class and loading an SCXML file dynamically or by using the Qt SCXML Compiler to generate a subclass of QScxmlStateMachine. The communication with the SCXML document is provided by the signals and methods of the QScxmlStateMachine class. Qt SCXML also integrates tightly with Qt's meta-object system for signal triggered state transitions and setting properties and invoking methods on QObjects by states.

 

The Qt State Machine Framework versus Qt SCXML

With the Qt State Machine Framework each state and transition has to be created and connected from code. The functionality of these state machine components are highly customizable but the more complicated the state machine gets the harder it is to keep everything in mind for the developers. Creating simple state machines is fast and  doesn’t require any tools or knowledge of a specific file format.

The SCXML files for Qt SCXML can be created with any suitable tool, such as a text editor or a visual editor (Qt Creator features one). This allows for creating and modifying very complex state machines effortlessly, and also making them easier to understand. On the other hand the resulting state machine components are less customizable. Also Qt SCXML performs better in many ways regarding execution speed and memory footprint compared to the Qt State Machine Framework.

Changes in Qt 6

In Qt 6 both state machine modules were retained with some small arrangements. Both modules were updated to support building with cmake and C++ property bindings. Generally speaking the state machine modules are source compatible with their Qt 5 versions and users of the library should be able to continue with zero or only minor changes to their projects.

State Machine modules

The Qt State Machine Framework was moved into its own Qt State Machines module and therefore is no longer part of Qt Core. There were very few cross dependencies inside Qt Core which ultimately led to this decision. It can be found via the general Qt module listing in the Qt documentation now. The Qt SCXML module continues to exist as an independent and supported module.

Ecmascript data model moved to a plugin

SCXML gives authors the ability to define a first-class data model as part of the SCXML document. The data model offers the capability of storing, reading, and modifying a set of data that is internal to the state machine. The SCXML specification does not mandate any specific data model, but instead defines a set of abstract capabilities that can be realized by various languages, such as ECMAScript or XML/XPath. Qt SCXML supports the null data model, which must be supported by all conforming SCXML processors, and the ECMAScript data model. In addition, Qt SCXML provides its own C++ data model that is implemented by the QScxmlCppDataModel class. In Qt 5, the ECMAScript data model is linked to QML. In Qt 6, the ECMAScript data model was moved to a plugin which allows building of Qt SCXML without having to link to QML This change contributes to more flexible deploy options.

Qt bindable properties

Qt 6 introduced the concept of bindable properties for QObject based properties. Consequently,   

the C++ bindable property feature was applied to the state machine modules, such that users of these modules can benefit from its advantages.

Bug fixes

All high priority bugs and several less important bugs were fixed as part of porting the modules to Qt 6. The full list of changes can be found in the modules “Qt 6 changes” documentation (Changes to the Qt State Machine Framework, Changes to Qt SCXML).

Suggestions

We would be happy to hear your thoughts in the comments about these modules, their current state as you experienced them and ideas about how to improve them.   


Blog Topics:

Comments