QtScript: how to reload current script?
QScriptEngine has evaluate() method that can 开发者_如何转开发be used to load script, execute it and to run a specified function from already loaded script. But how to clear current script and load a new one? For example, i use evaluate() to load a script from file and then evaluate() to get a script functions and call them. But what can i do to clear current script and load a new one from a different file? Deleting and creating QScriptEngine seems like a solution, but it likes to be created in GUI thread (due to QScriptEngineDebugger) while all script operations are performed in separate thread. So is it any way to clear current script without re-creating QScriptEngine object?
engine.pushContext();
engine.evaluate("...");
engine.popContext();
engine.pushContext();
engine.evaluate("...");
engine.popContext();
Calling pushContext() before evaluating a script and calling popContext() before evaluating a new script will effectively clear all script data.
I ran into this problem, and would like to improve Eye of Hell's answer (thanks, by the way!), as it leaves out an important detail.
I'll use a cut down version of my problem, where I am reusing a QScriptEngine
object and wanted to ensure that nothing was left behind between evaluations. In particular, I wanted to ensure that the onEquipped
function was not called for the "RC Helicopter Controller"
entity, as it doesn't change its sprite when it is equipped and hence doesn't define an onEquipped
function in its script file. Simply using pushContext()
and popContext()
results in nothing being called at all:
#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;
}
The function call seems to happen on the original context, not the current one. Upon looking at QScriptEngine::pushContext() documentation, I saw that you need to explicitly use the context returned from it, and on top of that, you must use QScriptEngine::activationContext() to access any variables:
#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;
}
changing pixmap to equipped sprite for Pistol
You could try to set an empty object to http://qt.nokia.com/doc/4.6/qscriptengine.html#setGlobalObject
Maybe that works.
精彩评论