1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
/******************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtScxml module.
**
** $QT_BEGIN_LICENSE:COMM$
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** $QT_END_LICENSE$
**
******************************************************************************/
/*!
\page qtscxml-index.html
\title Qt SCXML
\brief The Qt SCXML module provides functionality to create state machines
from SCXML files.
The Qt SCXML module provides functionality to create state machines from
\l {SCXML Specification}{SCXML} files. This includes both dynamically
creating state machines (loading the SCXML file and instantiating states
and transitions) and generating a C++ file that has a class implementing
the state machine. It also contains functionality to support data models
and executable content.
\section1 Getting Started
Both the dynamically created and the compiled state machines behave in the
same way, have the same properties, states, data model, and so on. They only
differ in the way they are instantiated. To dynamically create one in C++
from an SCXML file, you can use:
\code
auto *stateMachine = QScxmlStateMachine::fromFile("MyStatemachine.scxml");
\endcode
Or, in QML:
\qml
import Scxml 1.0
Item {
property QtObject stateMachine: scxmlLoader.stateMachine
StateMachineLoader {
id: scxmlLoader
filename: "statemachine.scxml"
}
}
\endqml
A compiled state machine can be instantiated the same way as any C++
object:
\code
auto *stateMachine = new MyStatemachine;
\endcode
Or:
\code
MyStatemachine stateMachine;
\endcode
To use a compiled state machine in QML, you can assign it to a context
property:
\code
MyStatemachine stateMachine;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("stateMachine", &stateMachine);
\endcode
To compile a state machine, the following lines have to be added to a
.pro file:
\badcode
QT += scxml
STATECHARTS = MyStatemachine.scxml
\endcode
This will tell qmake to run \e qscxmlc which generates MyStatemachine.h
and MyStatemachine.cpp, and adds them to \l [QMake] HEADERS and
\l [QMake] SOURCES variables.
After instantiating a state machine, you can connect to any state's
active property as follows. For example, if the state machine for a
traffic light has a state indicating that the light is red (which has the
convenient id "red" in the scxml file), you can write:
\code
QObject::connect(stateMachine->red(), &QAbstractState::activeChanged,
[stateMachine](){
qDebug() << (stateMachine->red()->active() ? "entered" : "exited") << "the red state";
});
\endcode
And in QML:
\qml
Light {
id: greenLight
color: "green"
visible: stateMachine.green.active
}
\endqml
If you want to be notified when a state machine sends out an event, you
can connect to the corresponding signal. For example, for a media player
state machine which indicates that playback has stopped by sending an
event, you can write:
\code
QObject::connect(stateMachine, &MediaPlayer::event_playbackStopped, [](){
qDebug() << "Stopped!";
});
\endcode
And in QML:
\qml
Connections {
target: stateMachine
onEvent_playbackStopped: console.log("Stopped!")
}
\endqml
Sending events to a state machine is equally simple. You can call (or
connect to) the slot:
\code
stateMachine->event_tap_song(QVariantMap({
std::make_pair("artist", "Fatboy Slim"),
std::make_pair("title", "The Rockafeller Skank")
});
\endcode
This will generate a "tap_song" event with the map contents available in
_event.data inside the state machine. In QML:
\code
stateMacine.event_tap_song({
"artist": "Fatboy Slim"
"title": "The Rockafeller Skank"
})
\endcode
Any invoked state machine with a name property will also show up as a
property on its parent state machine.
\section1 SCXML Compliance
Qt SCXML supports the following data models:
\list
\li null data model, as described in B.1 of the \l {SCXML specification}
\li ECMAScript data model, as described in B.2 of the
\l {SCXML specification}
\li C++ data model, as described in the QScxmlCppDataModel documentation
\endlist
The Qt SCXML implementation is SCXML compliant, with a few exceptions:
\list
\li Event data (\c _event.data) is implemented as a QVariant. If parameters
are passed to \c <send>, the QVariant holds a QVariantMap, so multiple
parameters with the same name are not supported.
\li There is no "raw" representation of an event.
\li The (optional) basic http event I/O processor is not supported.
\li The contents of a \c <script> tag and a \c <data> tag must be valid for
the chosen data model. So, as an example: XML content inside <data> is
not supported. However, the ECMAScript data model does support data in
JSON format.
\li The only service that can be instantiated with \c <invoke> is another
SCXML state machine.
\li To keep the behavior of dynamically created state machines and compiled
state machines the same, the \e typeexpr and \e srcexpr attributes are
not supported. Moreover, if a \c <content> tag is
used inside an \c <invoke> tag, that content must be XML. Specifically,
dynamically creating SCXML, for example by concatenating strings with
the ECMAScript data model, is not supported.
\endlist
The Qt SCXML implementation extends SCXML in the following ways:
\list
\li For communication purposes the \c <send> tag supports an extra
value \c "qt:signal" accepted by the attribute \c type.
The generated state machine or the state machine which has loaded
the SCXML file dynamically will contain corresponding
signal, which name will consist of the \c event_ prefix
followed by the value of the \c event attribute inside the \c <send> tag.
All of the \c <param> children will be placed inside the
QMap<QString, QVariant> map, and this map will be passed as a
QVariant argument of the mentioned signal.
\li If the event is an error event, \c _event.errorMessage will contain a more
detailed description of the error.
\endlist
\section1 Logging Categories
The QtScxml module exports the following logging categories:
\table
\header
\li Logging Category
\li Description
\row
\li qscxmlLog
\li Enables QtScxml module log
\row
\li scxmlLog
\li Enables log of scxml documents
\endtable
\section1 Examples
\list
\li \l {Qt SCXML Examples}
\endlist
\section1 Reference
\list
\li \l {Qt SCXML C++ Classes} {C++ Classes and Namespaces}
\li \l {Qt SCXML QML Types} {QML Types}
\endlist
*/
|