QScriptEngine官方说明文档

本文深入探讨了 Qt Script Engine 的核心概念,包括如何创建、配置、执行和调试脚本,以及如何利用其强大的功能实现与 C++ 的无缝集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QScriptEngine类提供用于解释的Qt Script代码的环境。

 

包含:QScriptEngine
继承关系:QObject的子类

 

例一:

QScriptEngine myEngine;
QScriptValue three = myEngine.evaluate("1 + 2");

evaluate()返回一个QScriptValue保存的解释结果。该QScriptValue类提供函数计算结果并转换为不同的C++类型(例如QScriptValue:: toString()QScriptValue:: toNumber())。

 

例二:
下面的代码片段显示了一个脚本函数被定义,然后从C++中调用使用QScriptValue::()的调用的例子:

QScriptValue fun = myEngine.evaluate("(function(a, b)  { return a + b; })");
QScriptValueList args;
args << 1 << 2;
QScriptValue threeAgain = fun.call(QScriptValue(), args);

如可以从上面的代码段中可以看出,一个脚本被以字符串的形式提供给解释引擎。加载脚本的一种常见方法是通过读取一个文件的内容,并通过它来evaluate(),如下代码:

QString fileName = "helloworld.qs";
QFile scriptFile(fileName);
if (!scriptFile.open(QIODevice::ReadOnly))
    // handle error
QTextStream stream(&scriptFile);
QString contents = stream.readAll();
scriptFile.close();
myEngine.evaluate(contents, fileName);

上面我们通过文件名作为第二个参数来evaluate()。这并不影响解释的方式,第二个参数是用来识别脚本用于调试目的的general-purpose字符串(例如,我们的文件名现在将要通过uncaughtExceptionBacktrace() involving到脚本)。

 

引擎配置 
globalObject()函数返回与脚本引擎相关联的全局对象。全局对象的属性可从任何脚本代码访问(也就是说,它们是全局变量)。通常情况下,解释脚本之前,你会希望通过添加一个或多个属性的全局对象来配置脚本引擎:

myEngine.globalObject().setProperty("myNumber", 123);
...
QScriptValue myNumberPlusOne = myEngine.evaluate("myNumber + 1");

添加自定义属性的脚本环境或提供脚本API是脚本相对于应用程序定制的标准方法之一。通常这些自定义属性有由newQObject()newobject()函数,或者通过newFunction(创建构造函数)创建的对象。

 

脚本异常 
evaluate()可以抛出一个脚本异常(如由于语法错误);在这种情况下,返回值是一个被抛出(通常是一个错误的对象)的值。您可以检查是否解释器通过调用hasUncaughtException()导致了异常。在这种情况下,你可以调用的错误对象的toString()来获取错误消息。对于目前未捕获的异常,也可通过uncaughtException()。调用clearExceptions()将导致任何未捕获的异常被清除。

QScriptValue result = myEngine.evaluate(...);
if (myEngine.hasUncaughtException())  {
    int line = myEngine.uncaughtExceptionLineNumber();
    qDebug() << "uncaught exception at line" << line << ":" << result.toString();
}

checkSyntax()函数可以被用来确定是否代码已经有效地传递到evaluate()

 

脚本对象的创建 
使用newobject()来创建一个标准的Qt Script对象;这是相当于C++的new Object()。您可以使用该对象的特定功能,在QScriptValue操纵脚本对象(例如QScriptValue::setProperty())。同样,使用newArray()来创建一个Qt脚本数组对象。使用newDate()来创建一个日期对象,newRegExp()来创建一个RegExp对象等都是被允许的。

QObject的整合 
使用newQObject()来包装一个QObject的(或子类)的指针。newQObject()返回一个代理脚本对象、特性、子类、信号或QObject的槽,它可作为代理对象的属性。不需要任何绑定代码,因为它是使用Qt元对象系统动态地进行管理。

QPushButton button;
QScriptValue scriptButton = myEngine.newQObject(&button);
myEngine.globalObject().setProperty("button", scriptButton);
myEngine.evaluate("button.checkable = true");
qDebug() << scriptButton.property("checkable").toBoolean();
scriptButton.property("show").call(); //调用show()槽

使用qScriptConnect()来一个将一个QT的信号连接到一个脚本函数;这是与Qt脚本的QObject::connect()等效的。当一个脚本函数响应一个C++的信号调用,它可能会导致脚本异常;您可以连接到signalHandlerException()信号捕捉这样的异常。
使用newQMetaObject()来封装一个QMetaObject;这给你一个基于QObject的类的"script representation"。 newQMetaObject()返回一个代理脚本对象;可作为代理对象的属性的类的枚举值。您还可以指定用于构造类的对象(例如,当构造函数是从一个脚本调用)的函数。对于具有标准Qt类的构造函数,Qt的脚本可以为你提供一个默认的构造函数的脚本。详参scriptValueFromQMetaObject()

请参阅QtScript文档上的QObject集成的详细信息。

 

导入扩展 
使用importExtension()来导入基于插件的扩展到引擎。调用availableExtensions()来获取一个list内含所有可用的扩展。或调用importedExtensions()来获得一个list内含那些已导入扩展。
调用pushContext()打开一个新的变量域,popContext()来关闭当前作用域。如果含临时变量定义(例如var foo = 123;) 要安全的释放时,意味着解释已经完成。 【最后一句拿不准,原文为and popContext() to close the current scope. This is useful if you are implementing an extension that evaluates script code containing temporary variable definitions (e.g. var foo = 123;) that are safe to discard when evaluation has completed.


原生功能 
使用newFunction()来封装原生(C++)函数,包括自己构造自定义类型,然后这些可以从脚本代码被调用。想使用这些功能必须有QScriptEngine:: FunctionSignature()的家长签字。然后你可能会传递函数作为参数传递给newFunction()。这里是一个函数返回它的前两个参数的和的一个例子:

QScriptValue myAdd(QScriptContext *context, QScriptEngine *engine)
 {
   QScriptValue a = context->argument(0);
   QScriptValue b = context->argument(1);
   return a.toNumber() + b.toNumber();
}

若要公开这个功能的脚本代码,可以将其设置为全局对象的一个属性:

QScriptValue fun = myEngine.newFunction(myAdd);
myEngine.globalObject().setProperty("myAdd", fun);

一旦做到这一点,脚本代码可以用完全相同的方式调用你的函数,并作为一个正常的脚本函数:

QScriptValue result = myEngine.evaluate("myAdd(myNumber, 1)");

 

长时间运行脚本 
如果您需要解释从主(GUI)线程可能长时间运行的脚本,你应该先调用setProcessEventsInterval(),以确保该图形用户界面保持响应。你可以通过调用abortEvaluation()终止当前正在运行的脚本。你可以通过调用isEvaluating()确定引擎是否正在运行的脚本。

 

垃圾回收 
Qt的脚本对象可以被垃圾回收,若是这样,他们将不再允许被引用。不过没有人知道自动垃圾回收将会何时发生。 
CollectGarbage()函数可以被调用来显式地请求垃圾回收。 
reportAdditionalMemoryCost()函数可以被调用,以表明一个Qt Script对象占用的并非是由脚本环境管理的内存。报告的额外成本使得垃圾回收器更容易被触发。这可能是有用的,例如在许多Qt规则中,原生的Qt Script对象会被分配。

 

核心调试/跟踪功能 
Qt4.4以来,您可以通过QScriptEngineAgent接口获取有关的脚本执行(如脚本函数调用和语句的执行)的事件通知;看到setAgent()函数。这可以被用来实现调试和QScriptEngine的分析。

更多详情,请见QScriptValueQScriptContextQScriptEngineAgent等类的说明文档。

 

<think>嗯,用户想了解QJSEngine的使用方法和文档。首先,我需要回顾一下QJSEngine的基本概念。QJSEngine是Qt框架中的一个模块,用于执行JavaScript代码。和之前的QScriptEngine不同,它基于JavaScriptCore,可能更现代一些。用户可能是在开发中遇到了需要嵌入脚本功能的情况,比如用Qt做桌面应用,想扩展功能。 接下来,我应该检查用户提供的引用内容,看看有没有相关的信息。引用2提到了QJSEngine的基本用法,比如用evaluate方法执行脚本,返回结果。引用3比较了QScriptEngine和QJSEngine,指出QJSEngine是未来的方向,但可能功能还在完善中。引用5提到了QML和C++的交互,这可能和QJSEngine的使用场景相关,比如在QML中调用C++对象。 用户的问题集中在使用方法和文档,所以需要分步骤说明。首先,基本用法,比如如何创建引擎,执行脚本,获取结果。然后可能需要提到如何将C++对象暴露给JS环境,比如使用setContextProperty,这点引用5有提到。此外,错误处理也很重要,比如捕获异常。 另外,用户可能想知道如何与Qt的其他模块集成,比如QML。不过引用3提到QJSEngine和Web模块可能不兼容,需要注意这一点。文档方面,Qt官方文档应该是最权威的,所以需要给出链接。可能用户遇到的问题是无法直接包含某些头文件,比如引用1中的情况,可能需要检查是否正确包含模块和配置.pro文件。 还需要考虑用户的实际应用场景,比如是否需要在JS中调用C++函数,或者反之。这时候可能需要使用Q_INVOKABLE宏或者注册全局对象。此外,性能方面,QJSEngine可能不如V8引擎,但对于一般应用足够。 最后,生成相关问题的时候,应该围绕用户可能遇到的后续问题,比如调试、性能优化、与QML的交互等。要确保回答结构清晰,步骤明确,用户能够一步步按照指导操作。</think>以下是对QJSEngine使用方法的详细说明: ### QJSEngine 基础使用 QJSEngine是Qt提供的JavaScript引擎实现,基于ECMAScript 5标准,适用于需要脚本扩展功能的Qt应用程序开发[^3]。 #### 1. 基本脚本执行 创建引擎并执行简单脚本: ```cpp QJSEngine engine; QJSValue result = engine.evaluate("1 + 2 * 3"); if (!result.isError()) { qDebug() << "计算结果:" << result.toInt(); // 输出7 } else { qWarning() << "执行错误:" << result.toString(); } ``` #### 2. 暴露C++对象 通过`setContextProperty`实现双向交互(注意需在加载脚本前设置)[^5]: ```cpp // 创建自定义对象 class DataManager : public QObject { Q_OBJECT public: Q_INVOKABLE void updateValue(int v) { m_value = v; } int value() const { return m_value; } private: int m_value = 0; }; // 注册到引擎 DataManager data_mgr; engine.globalObject().setProperty("DATAMGR", engine.newQObject(&data_mgr)); ``` #### 3. 函数调用与异常处理 ```cpp // 定义JS函数 QJSValue func = engine.evaluate("(function(a, b) { return a + b; })"); if (func.isCallable()) { QJSValueList args; args << 10 << 20; QJSValue ret = func.call(args); if (!ret.isError()) { qDebug() << "函数结果:" << ret.toInt(); // 输出30 } } ``` ### 文档参考 1. **Qt官方文档**:https://doc.qt.io/qt-5/qjsengine.html 2. **API说明**: - `evaluate()`:执行JS代码字符串 - `newQObject()`:封装QObject对象到JS环境 - `globalObject()`:获取全局作用域对象 ### 开发注意事项 1. 在.pro文件中添加`QT += qml`模块依赖 2. 复杂数据类型需通过`QVariant`转换 3. 异步操作建议结合`QJSPromise`实现
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值