有没有办法在 QScriptEngine#pushContext/popContext 之外维护 Qt 脚本上下文环境?
Is there a way to maintain Qt script context environment outside of QScriptEngine#pushContext/popContext?
在Qt 4.8 的脚本引擎中,"local" 变量可以通过 设置。这只能在 push/pop 调用中完成,因为那是唯一可用的地方 QScriptContext
并且 AFAICT 没有等效的 QScriptEngine#evaluate
需要 QScriptContext
用作环境:
QScriptEngine engine;
QScriptContext *local;
local = engine.pushContext();
local->activationObject().setProperty("value", 2); // set value=2
qDebug() << engine.evaluate("value").toNumber(); // outputs 2
engine.popContext();
有没有什么方法可以维护 在 调用 push/pop 之外进行评估的环境?例如,我尝试创建一个 QScriptValue
用作激活对象,然后将其设置为:
QScriptEngine engine;
QScriptContext *local;
// Use ao as activation object, set variables here, prior to pushContext.
QScriptValue ao;
ao.setProperty("value", 1);
// Test with ao:
local = engine.pushContext();
local->setActivationObject(ao);
qDebug() << engine.evaluate("value").toNumber();
engine.popContext();
但这不起作用。它输出 nan
而不是 1
,因为 value
未定义。由于某种原因 setActivationObject
没有更改值。
我的总体目标是:
- 在评估代码之外设置本地环境。
- 然后在
pushContext
和 popContext
调用之间评估脚本时使用该预配置的本地环境,而不必每次都重新设置该环境中的所有变量。
所以:
- 有办法吗?
- 有没有可能是我在正确的轨道上,但是
ao
设置不正确?例如,有一个未记录的 QScriptEngine#newActivationObject()
在使用时会产生 "unimplemented" 错误,也许这是一个提示?
我如何设置本地上下文,但基本上不必在每次推送上下文时都重新配置它(因为每次弹出上下文时它基本上都永远丢失了)。
您可以使用全局对象。它将在所有评估中共享 属性 值:
#include <QCoreApplication>
#include <QDebug>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptContext>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
engine.globalObject().setProperty("value", 2);
engine.globalObject().setProperty("value2", 3);
qDebug() << engine.evaluate("value").toNumber(); // outputs 2
qDebug() << engine.evaluate("value2").toNumber(); // outputs 3
return a.exec();
}
或者如果您不想要全局范围:
#include <QCoreApplication>
#include <QDebug>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptContext>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptContext *context;
QScriptValue scope = engine.newObject();
scope.setProperty("value", 1);
scope.setProperty("value2", 2);
context = engine.pushContext();
context->pushScope(scope);
qDebug() << engine.evaluate("value").toNumber(); // outputs 1
qDebug() << engine.evaluate("value2").toNumber(); // outputs 2
engine.popContext();
return a.exec();
}
在Qt 4.8 的脚本引擎中,"local" 变量可以通过QScriptContext
并且 AFAICT 没有等效的 QScriptEngine#evaluate
需要 QScriptContext
用作环境:
QScriptEngine engine;
QScriptContext *local;
local = engine.pushContext();
local->activationObject().setProperty("value", 2); // set value=2
qDebug() << engine.evaluate("value").toNumber(); // outputs 2
engine.popContext();
有没有什么方法可以维护 在 调用 push/pop 之外进行评估的环境?例如,我尝试创建一个 QScriptValue
用作激活对象,然后将其设置为:
QScriptEngine engine;
QScriptContext *local;
// Use ao as activation object, set variables here, prior to pushContext.
QScriptValue ao;
ao.setProperty("value", 1);
// Test with ao:
local = engine.pushContext();
local->setActivationObject(ao);
qDebug() << engine.evaluate("value").toNumber();
engine.popContext();
但这不起作用。它输出 nan
而不是 1
,因为 value
未定义。由于某种原因 setActivationObject
没有更改值。
我的总体目标是:
- 在评估代码之外设置本地环境。
- 然后在
pushContext
和popContext
调用之间评估脚本时使用该预配置的本地环境,而不必每次都重新设置该环境中的所有变量。
所以:
- 有办法吗?
- 有没有可能是我在正确的轨道上,但是
ao
设置不正确?例如,有一个未记录的QScriptEngine#newActivationObject()
在使用时会产生 "unimplemented" 错误,也许这是一个提示?
我如何设置本地上下文,但基本上不必在每次推送上下文时都重新配置它(因为每次弹出上下文时它基本上都永远丢失了)。
您可以使用全局对象。它将在所有评估中共享 属性 值:
#include <QCoreApplication>
#include <QDebug>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptContext>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
engine.globalObject().setProperty("value", 2);
engine.globalObject().setProperty("value2", 3);
qDebug() << engine.evaluate("value").toNumber(); // outputs 2
qDebug() << engine.evaluate("value2").toNumber(); // outputs 3
return a.exec();
}
或者如果您不想要全局范围:
#include <QCoreApplication>
#include <QDebug>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptContext>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptContext *context;
QScriptValue scope = engine.newObject();
scope.setProperty("value", 1);
scope.setProperty("value2", 2);
context = engine.pushContext();
context->pushScope(scope);
qDebug() << engine.evaluate("value").toNumber(); // outputs 1
qDebug() << engine.evaluate("value2").toNumber(); // outputs 2
engine.popContext();
return a.exec();
}