2010-01-11 92 views
4

QScriptEngine有evaluate()方法,可用于加载脚本,执行脚本并从已加载的脚本运行指定的函数。但是,如何清除当前脚本并加载新脚本?例如,我使用evaluate()从文件加载脚本,然后使用evaluate()来获取脚本函数并调用它们。但我能做些什么来清除当前脚本并从另一个文件加载新脚本?删除和创建QScriptEngine看起来像是一种解决方案,但它喜欢在GUI线程中创建(由于QScriptEngineDebugger),而所有脚本操作都是在单独的线程中执行的。那么是否有什么方法可以在不重新创建QScriptEngine对象的情况下清除当前脚本?QtScript:如何重新加载当前脚本?

回答

2

我遇到了这个问题,并想改善地狱之眼的答案(顺便说一句,谢谢),因为它遗漏了一个重要的细节。

我将使用我的问题的减少版本,在那里我重新使用QScriptEngine对象,并希望确保在评估之间不留下任何东西。特别是,我希望确保onEquipped函数未被"RC Helicopter Controller"实体调用,因为它在装备时不会更改其精灵,因此在其脚本文件中没有定义onEquipped函数。只需用pushContext()popContext()结果没有被调用都:

#include <QtCore> 
#include <QtScript> 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication app(argc, argv); 

    QScriptEngine scriptEngine; 

    scriptEngine.pushContext(); 
    scriptEngine.evaluate("function onEquipped(entity) { print('changing pixmap to equipped sprite for ' + entity); }").toString(); 
    QScriptValueList args; 
    args << QScriptValue("Pistol"); 
    scriptEngine.globalObject().property("onEquipped").call(QScriptValue(), args); 
    scriptEngine.popContext(); 

    scriptEngine.pushContext(); 
    args.clear(); 
    args << QScriptValue("RC Helicopter Controller"); 
    scriptEngine.globalObject().property("onEquipped").call(QScriptValue(), args); 
    scriptEngine.popContext(); 

    return 0; 
} 

函数调用,似乎在原有范围内,而不是当前的情况发生。在观看QScriptEngine::pushContext()文档,我看到你需要明确使用从它返回的上下文,以及最重要的是,你必须使用QScriptEngine::activationContext()访问任何变量:

#include <QtCore> 
#include <QtScript> 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication app(argc, argv); 

    QScriptEngine scriptEngine; 

    scriptEngine.pushContext(); 
    scriptEngine.evaluate("function onEquipped(entity) { print('changing pixmap to equipped sprite for ' + entity); }").toString(); 
    QScriptValueList args; 
    args << QScriptValue("Pistol"); 
    scriptEngine.currentContext()->activationObject().property("onEquipped").call(QScriptValue(), args); 
    scriptEngine.popContext(); 

    scriptEngine.pushContext(); 
    args.clear(); 
    args << QScriptValue("RC Helicopter Controller"); 
    scriptEngine.currentContext()->activationObject().property("onEquipped").call(QScriptValue(), args); 
    scriptEngine.popContext(); 

    return 0; 
} 

变化的像素图,为装备精灵手枪

0

你可以尝试一个空的对象设置为http://qt.nokia.com/doc/4.6/qscriptengine.html#setGlobalObject

也许这工作。

+0

全局对象只是定义了什么“这”将引用内部脚本:(。它没有连接到脚本代码本身 – grigoryvp 2010-01-11 12:20:06

+0

你至少试一试呢?至于我记得,功能是该对象的一部分。 – guruz 2010-01-11 13:24:48

+0

QT函数可用于脚本,而不是脚本函数。 – grigoryvp 2010-01-11 16:47:13

7
engine.pushContext(); 
engine.evaluate("..."); 
engine.popContext(); 
engine.pushContext(); 
engine.evaluate("..."); 
engine.popContext(); 

在评估脚本和在评估新脚本之前调用popContext()之前调用pushContext()将有效地清除所有脚本数据。