QtScript: как перезагрузить текущий скрипт? - PullRequest
4 голосов
/ 11 января 2010

QScriptEngine имеет методvalu (), который можно использовать для загрузки скрипта, его выполнения и запуска указанной функции из уже загруженного скрипта.Но как очистить текущий скрипт и загрузить новый?Например, я использую valu (), чтобы загрузить сценарий из файла, а затем valu (), чтобы получить функции сценария и вызвать их.Но что я могу сделать, чтобы очистить текущий скрипт и загрузить новый из другого файла?Удаление и создание QScriptEngine выглядит как решение, но ему нравится создаваться в потоке GUI (из-за QScriptEngineDebugger), в то время как все операции сценария выполняются в отдельном потоке.Так есть ли способ очистить текущий скрипт без повторного создания объекта QScriptEngine?

Ответы [ 3 ]

7 голосов
/ 12 января 2010
engine.pushContext();
engine.evaluate("...");
engine.popContext();
engine.pushContext();
engine.evaluate("...");
engine.popContext();

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

2 голосов
/ 17 апреля 2014

Я столкнулся с этой проблемой и хотел бы улучшить ответ «Глаза ада» (спасибо, кстати!), Так как он не учитывает важную деталь.

Я буду использовать урезанную версию своей проблемы, где я повторно использую объект 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 :: активацииContext () для доступа к любым переменным:

#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 голосов
/ 11 января 2010

Вы можете попробовать установить пустой объект на http://qt.nokia.com/doc/4.6/qscriptengine.html#setGlobalObject

Может быть, это работает.

...