QScxmlCppDataModel Class

QScxmlCppDataModel 类是Qt SCXML 状态机的 C++ 数据模型。更多

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

公共函数

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

重新实现的公共函数

virtual void evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) override
virtual void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, QScxmlDataModel::ForeachLoopBody *body) override
virtual void evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) override
virtual bool hasScxmlProperty(const QString &name) const override
virtual QVariant scxmlProperty(const QString &name) const override
virtual void setScxmlEvent(const QScxmlEvent &event) override
virtual bool setScxmlProperty(const QString &name, const QVariant &value, const QString &context) override
virtual bool setup(const QVariantMap &initialDataValues) override

详细说明

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

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

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

数据模型属性的格式为:cplusplus:<class-name>:<classdef-header> 。因此,在上面的示例中,应该有一个包含 QScxmlCppDataModel 子类的文件thedatamodel.h,其中至少包含以下内容:

#include <QScxmlCppDataModel>

class TheDataModel: public QScxmlCppDataModel
{
    Q_OBJECT
    Q_SCXML_DATAMODEL
    ...
};

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

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

<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 指针也被捕获,您可以调用或访问数据模型(上例中的媒体属性)。有关完整示例,请参阅SCXML 媒体播放器

另请参阅 QScxmlStateMachineQScxmlDataModel

成员函数文档

[explicit] QScxmlCppDataModel::QScxmlCppDataModel(QObject *parent = nullptr)

使用父对象parent 创建新的 C++ 数据模型。

[override virtual] void QScxmlCppDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok)

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

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

[override virtual] 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>

[override virtual] void QScxmlCppDataModel::evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok)

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

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

[override virtual] 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

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

有关_event 变量的说明,请参阅SCXML 规范 - 5.10 系统变量。

返回当前正在处理的事件。

另请参阅 setScxmlEvent().

[override virtual] QVariant QScxmlCppDataModel::scxmlProperty(const QString &name) const

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

此方法总是返回空QVariant ,并忽略name 。重载该方法可通过各种元素的location 属性实现数据模型属性的查询。

另请参阅 setScxmlProperty().

[override virtual] void QScxmlCppDataModel::setScxmlEvent(const QScxmlEvent &event)

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

设置下一步要处理的event

另请参阅 QScxmlCppDataModel::scxmlEvent

[override virtual] 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() 。

[override virtual invokable] bool QScxmlCppDataModel::setup(const QVariantMap &initialDataValues)

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

在状态机初始化过程中调用,使用数据模型变量的初始值来设置状态机,初始值由数据模型变量的键initialDataValues 指定。这些值是<param> 标记在<invoke> 元素中指定的值。

成功时返回true

注: 可通过元对象系统和 QML 调用此函数。参见Q_INVOKABLE

另请参阅 QScxmlStateMachine::init

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.