在评估之前设置 QScriptValue-local 值
Setting QScriptValue-local values prior to evaluating
在 Qt 4.8 中,从 C++ 端,是否可以在 QScriptEngine
中设置 QScriptValue
-local 值?
例如,假设我有:
QScriptEngine engine;
engine.globalObject().setProperty("glob", 1000);
// ???: Set loc to, say, 42.
QScriptValue expr1 = engine.evaluate("glob + loc");
qDebug() << expr1.toNumber();
// ???: Set loc to, say, 99.
QScriptValue expr2 = engine.evaluate("glob + loc");
qDebug() << expr2.toNumber();
我希望它的输出是:
1042
1099
上面人为设计的示例的明显解决方案是使 "loc" 全局化并相应地设置 + 重置它,但出于分散注意力的原因,这不是我要找的。我想要:
- "loc" 对每个
QScriptValue
都是本地的
- 不要人为地修改脚本字符串,例如在脚本前添加
QString().sprintf("loc = %d;", 42)
或其他内容。
- 只使用一个
QScriptEngine
。
我唯一能想到的尝试是:
QScriptValue expr1 = engine.evaluate("glob + loc");
expr1.setProperty("loc", 42);
qDebug() << expr1.toNumber();
但似乎该值已由 evaluate()
完全评估,因此 setProperty()
没有效果(这并不奇怪)。
我也看了一眼 QScriptProgram
希望它提供了一个程序本地环境,但是唉。
我正在看文档,我post之后会继续看文档,但这是我第一次使用QScriptEngine
而且我不得不承认我的大脑正在变得糊涂,所以如果它就在那里并且非常明显,我深表歉意。我将接受 RTFM 作为有效答案。
我想通了,至少我认为这是最好的方法。关键是 QScriptEngine#pushContext()
和 #popContext()
:
QScriptEngine engine;
engine.globalObject().setProperty("glob", 1000);
QScriptContext *local;
local = engine.pushContext();
local->activationObject().setProperty("loc", 42);
QScriptValue expr1 = engine.evaluate("glob + loc");
engine.popContext();
qDebug() << expr1.toNumber();
local = engine.pushContext();
local->activationObject().setProperty("loc", 99);
QScriptValue expr2 = engine.evaluate("glob + loc");
engine.popContext();
qDebug() << expr2.toNumber();
并且只要给定的 QScriptContext
在堆栈上处于活动状态,所有 QScriptValue
评估都会使用它。先前存在的同名变量将被后续上下文覆盖。
我想需要注意的是,如果您要使用多个线程和一个引擎,则必须使 push → 所有评估 → pop 原子化,而不是单个评估。我希望有一种方法可以将上下文传递给 evaluate()
.
在 Qt 4.8 中,从 C++ 端,是否可以在 QScriptEngine
中设置 QScriptValue
-local 值?
例如,假设我有:
QScriptEngine engine;
engine.globalObject().setProperty("glob", 1000);
// ???: Set loc to, say, 42.
QScriptValue expr1 = engine.evaluate("glob + loc");
qDebug() << expr1.toNumber();
// ???: Set loc to, say, 99.
QScriptValue expr2 = engine.evaluate("glob + loc");
qDebug() << expr2.toNumber();
我希望它的输出是:
1042
1099
上面人为设计的示例的明显解决方案是使 "loc" 全局化并相应地设置 + 重置它,但出于分散注意力的原因,这不是我要找的。我想要:
- "loc" 对每个
QScriptValue
都是本地的
- 不要人为地修改脚本字符串,例如在脚本前添加
QString().sprintf("loc = %d;", 42)
或其他内容。 - 只使用一个
QScriptEngine
。
我唯一能想到的尝试是:
QScriptValue expr1 = engine.evaluate("glob + loc");
expr1.setProperty("loc", 42);
qDebug() << expr1.toNumber();
但似乎该值已由 evaluate()
完全评估,因此 setProperty()
没有效果(这并不奇怪)。
我也看了一眼 QScriptProgram
希望它提供了一个程序本地环境,但是唉。
我正在看文档,我post之后会继续看文档,但这是我第一次使用QScriptEngine
而且我不得不承认我的大脑正在变得糊涂,所以如果它就在那里并且非常明显,我深表歉意。我将接受 RTFM 作为有效答案。
我想通了,至少我认为这是最好的方法。关键是 QScriptEngine#pushContext()
和 #popContext()
:
QScriptEngine engine;
engine.globalObject().setProperty("glob", 1000);
QScriptContext *local;
local = engine.pushContext();
local->activationObject().setProperty("loc", 42);
QScriptValue expr1 = engine.evaluate("glob + loc");
engine.popContext();
qDebug() << expr1.toNumber();
local = engine.pushContext();
local->activationObject().setProperty("loc", 99);
QScriptValue expr2 = engine.evaluate("glob + loc");
engine.popContext();
qDebug() << expr2.toNumber();
并且只要给定的 QScriptContext
在堆栈上处于活动状态,所有 QScriptValue
评估都会使用它。先前存在的同名变量将被后续上下文覆盖。
我想需要注意的是,如果您要使用多个线程和一个引擎,则必须使 push → 所有评估 → pop 原子化,而不是单个评估。我希望有一种方法可以将上下文传递给 evaluate()
.