QIfSimulationEngine 类
提供从 QML 脚本模拟后端的方式。更多...
头文件 | #include <QIfSimulationEngine> |
qmake | QT += interfaceframework |
继承 | QQmlApplicationEngine |
公共函数
QIfSimulationEngine(QObject *parent = nullptr) | |
QIfSimulationEngine(const QString &identifier, QObject *parent = nullptr) | |
void | loadSimulation(const QUrl &file) |
void | loadSimulationData(const QString &dataFile) |
void | registerSimulationInstance(T *instance, const char *uri, int versionMajor, int versionMinor, const char *qmlName) |
相关非成员
QVariant | qtif_convertFromJSON(const QVariant &value) |
宏
QIF_SIMULATION_TRY_CALL(instance_type, function, ret_type, ...) | |
QIF_SIMULATION_TRY_CALL_FUNC(instance_type, function, ret_func, ...) |
详细描述
此类是扩展的 QQmlApplicationEngine,可用来加载 QML 文件。它专门为仿真后端编写从 QML 中的行为脚本而设计。对其功能概述,请参阅Qt 接口框架仿真系统。
与世界末日相比,QIfSimulationEngine 提供一个额外的模板函数,称为 registerSimulationInstance()。使用此函数将类实例注册为 QML 类型。在 QML 文件中,此 QML 类型可用于定义函数调用的行为,更新属性或发出信号。
注册实例
您可以通过调用 registerSimulationInstance()将任何从 QObject 派生的类的实例注册到 QIfSimulationEngine。类似于 qmlRegisterTypes,提供的 URI、版本和名称用于从 QML 中导入类型。
class MyClass : public QObject { Q_OBJECT Q_PROPERTY(int currentTemperature READ currentTemperature WRITE setCurrentTemperature NOTIFY currentTemperatureChanged) ... }
此简单类的实例可以按以下方式注册
QIfSimulationEngine engine; MyClass myClass; engine.registerSimulationInstance<MyClass>(&myClass, "Test", 1, 0, "MyClass"); engine.loadSimulation("simulation.qml")
已注册的实例具有任何暴露给 QML 的 C++ 类相同的约束,并需要使用 Q_PROPERTY、Q_INVOKABLE 或槽来使功能可用。
从 QML 使用类型
将实例注册到引擎后,该类型可以像任何其他声明性形式的 QML 元素一样使用。
import QtQuick import Test Item { MyClass { id: myClass Component.onCompleted: currentTemperature = 10; } Timer { running: true repeat: true interval: 1000 onTriggered: myClass.currentTemperature++; } }
此 QML 文件将 myClass
的 currentTemperature
初始化为值 10
并每秒增加。
同样地,可以从 C++ 端更新值,而 QML 端可以响应变化。例如,以下 QML 片段每当 currentTemperature
改变时打印它。
import QtQuick import Test MyClass { onCurrentTemperatureChanged: print(currentTemperature) }
当 myClass
变量更新时,将调用槽。
QIfSimulationEngine engine; MyClass myClass; engine.registerSimulationInstance<MyClass>(&myClass, "Test", 1, 0, "MyClass"); engine.loadSimulation("simulation.qml") ... myClass.setCurrentTemperature(100);
从实例到引擎的前向调用
您还可以为 QML 中的 invokable 函数提供行为,但这需要您扩展公开的类。例如,通过向 setCurrentTemperature
设置器添加以下行
void MyClass::setCurrentTemperature(int currentTemperature) { QIF_SIMULATION_TRY_CALL(MyClass, "setCurrentTemperature", void, currentTemperature); if (m_currentTemperature == currentTemperature) return; m_currentTemperature = currentTemperature; emit currentTemperatureChanged(m_currentTemperature); }
现在调用 setCurrentTemperature()
将尝试将调用转发到 QML 实例,如果 QML 中定义了匹配签名的函数。如果成功,setCurrentTemperature()
将使用其返回值并避免运行原始的 C++ 函数。
使用以下 QML 片段,将跳过 C++ 设置器,并在控制台只发出错误
import QtQuick import Test MyClass { function setCurrentTemperature(temperature) { print("Updating the temperature is not possible") } }
在实例中重用现有行为
用 QML 行为替换 C++ 功能并不总是希望如此。然而,从 QML 也可以调用原始 C++ 行为。在这种情况下,原始 C++ 函数需要是 Q_INVOKABLE 或槽。类似地,这就像 C++ 中的函数重写一样工作,其中可以通过调用 <BaseClass>::<function>
访问被重写函数的功能。在公开的 QML 类型中,这可以通过在 Base
对象中调用函数来实现。
import QtQuick import Test MyClass { function setCurrentTemperature(temperature) { print("Updating the temperature: " + temperature ) Base.setCurrentTemperature(temperature) } }
以下 QML 片段在 QML 中重写了 setCurrentTemperature() 行为并打印新值的调试消息。使用 Base.setCurrentTemperature(temperature)
调用原始 C++ 行为。
多个 QML 实例
注册的实例作为普通 QML 类型公开。这使得在 QML 中有多个声明成为可能,从而有多个 QML 实例链接到相同的 C++ 实例。所有实例都可以更新和响应属性更改和信号发射,但应谨慎使用,因为这可能导致属性更新循环和其他问题。
将 C++ 函数调用转发到 QML 是有限的。每个调用仅转发到单个 QML 实例,因为返回值来自此调用。如果多个 QML 实例定义了相同的方法,则 C++ 调用始终转发到第一个注册的 QML 实例。
运行时覆盖
每个 QIfSimulationEngine 都可以接受一个额外的标识符,该标识符可以用作在运行时覆盖模拟 QML 文件或模拟数据文件。环境变量需要以下格式
QTIF_SIMULATION_OVERRIDE=<identifier>=<file>[;<identifier>=<file>] QTIF_SIMULATION_DATA_OVERRIDE=<identifier>=<file>[;<identifier>=<file>]
成员函数文档
[显式]
QIfSimulationEngine::QIfSimulationEngine(QObject *parent = nullptr)
使用指定的 parent 构造一个新 QIfSimulationEngine。
[显式]
QIfSimulationEngine::QIfSimulationEngine(const QString &identifier, QObject *parent = nullptr)
使用给定的 标识符 和 父对象 创建一个新的 QIfSimulationEngine。
可以使用 标识符 覆盖模拟 QML 文件或模拟数据文件。
另请参阅 运行时和覆盖。
void QIfSimulationEngine::loadSimulation(const QUrl &file)
将 QML 文件 作为模拟行为加载。
除了 QQmlApplicationEngine::load(),此函数还提供以下格式的环境变量来更改使用的主文件的功能
QTIF_SIMULATION_OVERRIDE=<identifier>=<file>[;<identifier>=<file>]
模拟引擎的标识符可以在其构造函数中设置。
void QIfSimulationEngine::loadSimulationData(const QString &dataFile)
加载提供的 dataFile 作为模拟数据文件。
给定的文件必须是 JSON 格式,在传递给 IfSimulator 全球对象进行解析之前,将在这里解析错误。此文件可以在运行时使用以下环境变量进行覆盖
QTIF_SIMULATION_DATA_OVERRIDE=<identifier>=<file>[;<identifier>=<file>]
模拟引擎的标识符可以在其构造函数中设置。
另请参阅IfSimulator。
template <typename T> void QIfSimulationEngine::registerSimulationInstance(T *instance, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
以 qmlName 的名称,在从 uri 导入的库中注册指定的 实例,版本号由 versionMajor 和 versionMinor 组成。
注意:已注册的实例仅适用于此 QIfSimulationEngine 实例。从另一个 QIfSimulationEngine 或 QQmlEngine 中使用它将不起作用并产生错误。
另请参阅qmlRegisterType。
相关非成员
QVariant qtif_convertFromJSON(const QVariant &value)
将 value 从 JSON 转换为有效的 C++ 类型。
提供的 JSON 值需要遵循 IfSimulator 数据格式。
宏文档
QIF_SIMULATION_TRY_CALL(instance_type, function, ret_type, ...)
尝试在 QML 已注册的 instance_type 实例中调用 function。可变参数作为参数传递给 QML 中的函数。
如果调用成功,将返回 ret_type 的值,并且在此宏之后的所有代码都将 不会 执行。
另请参阅QIF_SIMULATION_TRY_CALL_FUNC 和 从实例到引擎的转发调用。
QIF_SIMULATION_TRY_CALL_FUNC(instance_type, function, ret_func, ...)
尝试在 QML 已注册的 instance_type 实例中调用 function。可变参数作为参数传递给 QML 中的函数。
如果调用成功,通过 ret_func 传递的代码将被执行。这在需要首先转换返回值的情况下很有用。原始返回值作为 return_value
可用。
QIF_SIMULATION_TRY_CALL_FUNC(MyClass, "contactList", return return_value.toStringList());
另请参阅 QIF_SIMULATION_TRY_CALL 和 从实例向引擎转发调用。
© 2024 Qt 公司。本文档中的文档贡献包含各自的版权。提供的文档根据自由软件基金会发布的 GNU 自由文档许可协议第 1.3 版 的条款提供许可。Qt 和相应的标志是芬兰及/或其他国家的 Qt 公司的 商标。所有其他商标均属于各自的所有者。