QScxmlCppDataModel 类

QScxmlCppDataModel 类是一个用于 Qt SCXML 状态机的 C++ 数据模型。 更多信息...

头文件 #include <QScxmlCppDataModel>
CMakefind_package(Qt6 REQUIRED COMPONENTS Scxml)
target_link_libraries(mytarget PRIVATE Qt6::Scxml)
qmakeQT += scxml
继承 QScxmlDataModel

公共函数

QScxmlCppDataModel(QObject *parent = nullptr)
boolinState(const QString &stateName) const
const QScxmlEvent &scxmlEvent() const

重实现的公共函数

virtual voidevaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) override
virtual voidevaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, QScxmlDataModel::ForeachLoopBody *body) override
virtual voidevaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) override
virtual boolhasScxmlProperty(const QString &name) const override
virtual QVariantscxmlProperty(const QString &name) const override
virtual voidsetScxmlEvent(const QScxmlEvent &event) override
virtual boolsetScxmlProperty(const QString &name, const QVariant &value, const QString &context) override
virtual boolsetup(const QVariantMap &initialDataValues) override

详细描述

SCXML 的 C++ 数据模型允许你为 expr 属性和 <script> 元素编写 C++ 代码。数据模型的 data 部分由 QScxmlCppDataModel 的子类支持,Qt SCXML 编译器(qscxmlc)将为它生成分发方法。在运行时加载 SCXML 文件时不能使用。

使用方法是通过 <scxml> 元素的 datamodel 属性

<scxml datamodel="cplusplus:TheDataModel:thedatamodel.h"  ....>

datamodel 属性的格式是: cplusplus:<class-name>:<classdef-header>。因此,对于上面的例子,应该有一个包含 QScxmlCppDataModel 子类的文件 thedatamodel.h,该文件至少包含以下内容

#include "qscxmlcppdatamodel.h"

class TheDataModel: public QScxmlCppDataModel
{
    \Q_OBJECT
    Q_SCXML_DATAMODEL
};

Q_SCXML_DATAMODEL 必须出现在类定义的私有部分,例如在开括号之后,或者 Q_OBJECT 宏之后。这个宏展开成声明一些虚拟方法的声明,它们的实现由 Qt SCXML 编译器生成。

Qt SCXML 编译器将生成各种 evaluateTo 方法,并将表达式和脚本转换成这些方法中的lambda表达式。例如

<scxml datamodel="cplusplus:TheDataModel:thedatamodel.h" xmlns="http://www.w3.org/2005/07/scxml" version="1.0" name="MediaPlayerStateMachine">
    <state id="stopped">
        <transition event="tap" cond="isValidMedia()" target="playing"/>
    </state>

    <state id="playing">
        <onentry>
            <script>
                media = eventData().value(QStringLiteral(&quot;media&quot;)).toString();
            </script>
            <send event="playbackStarted">
                <param name="media" expr="media"/>
            </send>
        </onentry>
    </state>
</scxml>

这会导致

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(); }();
    // ....
}

因此,你不仅限于调用函数。在 <script> 元素中,你可以放置零个或多个 C++ 语句,并且在 condexpr 属性中,你可以使用任何可以转换为相应 bool 或 QVariant 的 C++ 表达式。此外,由于已经捕获了 this 指针,你可以调用或访问数据模型(如上方示例中的 media 属性)。有关完整示例,请参见 SCXML 媒体播放器

另请参阅 QScxmlStateMachineQScxmlDataModel

成员函数文档

[显式构造函数] QScxmlCppDataModel::QScxmlCppDataModel(QObject *parent = nullptr)

创建一个新的 C++ 数据模型,具有父对象 parent

[覆盖虚函数] void QScxmlCppDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok)

重实现了 QScxmlDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok)。

此方法不执行任何操作,忽略 id,并将 ok 设置为 false。在您的特定数据模型中重写它,以实现 <assign>

[覆盖虚函数] void QScxmlCppDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, QScxmlDataModel::ForeachLoopBody *body)

重实现了 QScxmlDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, QScxmlDataModel::ForeachLoopBody *body)。

此方法不执行任何操作,忽略 idbody,并将 ok 设置为 false。在您的特定数据模型中重写它,以实现 <foreach>

[覆盖虚函数] void QScxmlCppDataModel::evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok)

重实现了 QScxmlDataModel::evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok)。

此方法不执行任何操作,忽略 id,并将 ok 设置为 false。在您的特定数据模型中重写它,以实现 <data>

[覆盖虚函数] bool QScxmlCppDataModel::hasScxmlProperty(const QString &name) const

重实现了 QScxmlDataModel::hasScxmlProperty(const QString &name) const

此方法始终返回 false 并忽略 name。重写之,以通过各种元素的 location 属性实现数据模型属性的查找。

bool QScxmlCppDataModel::inState(const QString &stateName) const

如果状态机处于由 stateName 指定的状态,则返回 true,否则返回 false

const QScxmlEvent &QScxmlCppDataModel::scxmlEvent() const

存储状态机正在处理的当前事件。

请参阅SCXML 规范 - 5.10 系统变量以了解 _event 变量的描述。

返回正在处理的事件。

另请参阅 setScxmlEvent

[覆盖虚拟] QVariant QScxmlCppDataModel::scxmlProperty(const QString &name) const

重新实现: QScxmlDataModel::scxmlProperty(const QString &name) const.

该方法始终返回一个空 QVariant 并忽略 name。覆盖它来通过各种元素的 location 属性实现数据模型属性的查找。

另请参阅 setScxmlProperty

[覆盖虚拟] void QScxmlCppDataModel::setScxmlEvent(const QScxmlEvent &event)

重新实现: QScxmlDataModel::setScxmlEvent(const QScxmlEvent &event).

设置下一个要处理的事件。

另请参阅 QScxmlCppDataModel::scxmlEvent

[覆盖虚拟] bool QScxmlCppDataModel::setScxmlProperty(const QString &name, const QVariant &value, const QString &context)

重新实现: QScxmlDataModel::setScxmlProperty(const QString &name, const QVariant &value, const QString &context).

该方法始终返回 false 并忽略 namevaluecontext。覆盖它来通过各种元素的 location 属性实现数据模型属性的查找。

另请参阅 scxmlProperty

[覆盖虚拟可调用] bool QScxmlCppDataModel::setup(const QVariantMap &initialDataValues)

重新实现: QScxmlDataModel::setup(const QVariantMap &initialDataValues).

在状态机初始化期间被调用,使用通过它们的键指定的数据模型变量的初始值来设置状态机。这些是在 <invoke> 元素中通过 <param> 标签指定的值。

在成功时返回 true

注意: 此函数可以通过元对象系统和从 QML 调用。请参阅 Q_INVOKABLE

另请参阅 QScxmlStateMachine::init

© 2024 The Qt Company Ltd. 本文档中包含的贡献者的版权。本提供的文档是根据由自由软件基金会发布的 GNU自由文档许可协议版本1.3 许可的。Qt及其相关标志是芬兰及全球其他国家的The Qt Company Ltd.的商标。所有其他商标均为各自所有者的财产。