QScriptEngine имеет метод оценки(), который может использоваться для загрузки скрипта, выполнения его и для запуска указанной функции из уже загруженного скрипта. Но как очистить текущий скрипт и загрузить новый? Например, я использую функцию оценки() для загрузки сценария из файла, а затем для вычисления(), чтобы получить функции скрипта и вызвать их. Но что я могу сделать, чтобы очистить текущий скрипт и загрузить новый из другого файла? Удаление и создание QScriptEngine похоже на решение, но оно нравится создаваться в потоке графического интерфейса (из-за QScriptEngineDebugger), в то время как все операции с скриптами выполняются в отдельном потоке. Так можно ли очистить текущий скрипт без повторного создания объекта QScriptEngine?QtScript: как перезагрузить текущий скрипт?
ответ
Я столкнулся с этой проблемой и хотел бы улучшить ответ Глаза Ада (спасибо, кстати!), Так как он оставляет важную деталь.
Я использую сокращенную версию моей проблемы, где я повторно использую объект 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;
}
изменения растрового изображения в оборудованный спрайт для Пистолет
Вы могли бы попытаться установить пустой объект http://qt.nokia.com/doc/4.6/qscriptengine.html#setGlobalObject
Может быть, работает.
engine.pushContext();
engine.evaluate("...");
engine.popContext();
engine.pushContext();
engine.evaluate("...");
engine.popContext();
Вызова pushContext() перед вычислением сценария и вызова popContext() перед оценкой нового сценария будет эффективно удалить все данные сценария.
Глобальный объект просто определяет, что «это» будет ссылаться внутри скрипта :(. это не имеет никакого отношения к коду сценария самого – grigoryvp
ли вы по крайней мере попробовать это? насколько я помню, функции являются частью этого объекта. – guruz
Функции QT доступны из сценария, а не для скриптовых функций. – grigoryvp