发送数据到 C++ 数据模型和接收数据从 C++ 数据模型。
媒体播放器
demonstrates how to access data from a C++ data model. The data model enables writing C++ code for
expr
属性和
<script>
元素。
数据部分
的数据模型后援是子类化的
QScxmlCppDataModel
, for which the Qt SCXML compiler (
qscxmlc
) generates the dispatch methods.
UI 是使用 Qt Quick 创建的。
要运行范例从 Qt Creator ,打开 Welcome 模式,然后选择范例从 Examples 。更多信息,拜访 构建和运行范例 .
We specify the data model as a value of the
datamodel
属性在
<scxml>
element in the SCXML file:
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" name="MediaPlayerStateMachine" initial="stopped" datamodel="cplusplus:TheDataModel:thedatamodel.h"
The format of the
datamodel
attribute is:
cplusplus:<class-name>:<classdef-header>
. Therefore, we need a file called
thedatamodel.h
that contains a subclass of
QScxmlCppDataModel
:
#include "qscxmlcppdatamodel.h" #include <QtQml/qqml.h> class TheDataModel: public QScxmlCppDataModel { Q_OBJECT Q_SCXML_DATAMODEL
QScxmlCppDataModel
派生自
QObject
, so we add the
Q_OBJECT
macro in the private section of the definition, right after the opening bracket. We then place the
Q_SCXML_DATAMODEL
macro after
Q_OBJECT
. The macro expands to the declaration of virtual methods, the implementation of which is generated by the Qt SCXML compiler.
In the SCXML file, we specify C++ statements in the
<script>
element and use the
expr
attribute to access the data model:
<state id="stopped"> <transition event="tap" cond="isValidMedia()" target="playing"/> </state> <state id="playing"> <onentry> <script> media = eventData().value(QStringLiteral("media")).toString(); </script> <send event="playbackStarted"> <param name="media" expr="media"/> </send> </onentry> <onexit> <send event="playbackStopped"> <param name="media" expr="media"/> </send> </onexit> <transition event="tap" cond="!isValidMedia() || media == eventData().value(QStringLiteral("media"))" target="stopped"/> <transition event="tap" cond="isValidMedia() && media != eventData().value(QStringLiteral("media"))" target="playing"/> </state>
The Qt SCXML compiler generates the various
evaluateTo
methods and converts the expressions and scripts into lambdas inside those methods in
mediaplayer.cpp
:
bool TheDataModel::evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) { .... return [this]()->bool{ return isValidMedia(); }(); .... } QVariant TheDataModel::evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok) { .... return [this]()->QVariant{ return media; }(); .... } void TheDataModel::evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok) { .... [this]()->void{ media = eventData().value(QStringLiteral("media")).toString(); }(); .... }