本页内容

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"  ....>

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

#include <QScxmlCppDataModel>

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

Q_SCXML_DATAMODEL 必须出现在类定义的 private 部分,例如紧跟在左括号之后,或位于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++语句;而在cond 或expr属性中,您可以使用任何能够转换为相应bool或QVariant 类型的C++表达式。 此外,由于this 指针也被捕获,你可以调用或访问数据模型(如上例中的media属性)。完整示例请参阅SCXML媒体播放器。

另请参阅 QScxmlStateMachine 和QScxmlDataModel 。

成员函数文档

[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)。

该方法不执行任何操作,忽略id 和body ,并将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 ,并忽略name 、value 和context 。重写该方法以实现通过各种元素的location 属性查询数据模型属性。

另请参阅 scxmlProperty()。

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

重写自:QScxmlDataModel::setup(const QVariantMap &initialDataValues)。

在状态机初始化期间调用此函数,用于根据其键initialDataValues 所指定的数据模型变量的初始值来设置状态机。这些值由<invoke> 元素中的<param> 标签所指定。

成功时返回true 。

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

另请参阅 QScxmlStateMachine::init 。

© 2026 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.