2010-01-11 3 views
4

QScriptEngine имеет метод оценки(), который может использоваться для загрузки скрипта, выполнения его и для запуска указанной функции из уже загруженного скрипта. Но как очистить текущий скрипт и загрузить новый? Например, я использую функцию оценки() для загрузки сценария из файла, а затем для вычисления(), чтобы получить функции скрипта и вызвать их. Но что я могу сделать, чтобы очистить текущий скрипт и загрузить новый из другого файла? Удаление и создание QScriptEngine похоже на решение, но оно нравится создаваться в потоке графического интерфейса (из-за 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

+0

ли вы по крайней мере попробовать это? насколько я помню, функции являются частью этого объекта. – guruz

+0

Функции QT доступны из сценария, а не для скриптовых функций. – grigoryvp

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

Вызова pushContext() перед вычислением сценария и вызова popContext() перед оценкой нового сценария будет эффективно удалить все данные сценария.