Контекст для анонимной функции сценария qt?
Я хотел бы выполнить анонимную функцию сценария Qt из C++, но не могу понять, какой QScriptContext использовать.
Вот сценарий:
{
otherObject.Text = "Hello World";
setTimeout(function(otherObject) { otherObject.Text = "Goodbye World"; }, 9000 );
}
Вот метод setTimeout в C++:
QScriptValue setTimeout( QScriptContext* ctx, QScriptEngine* eng )
{
// How can I obtain the correct context and arg list for the anonymous function here?
}
Метод вызова объекта QScriptValue требует контекста и списка аргументов:
call( ctx->thisObject(), ctx->argumentsObject() );
редактировать: контекст может быть глобальным контекстом, но суть проблемы заключается в создании списка аргументов для вызова функции. Я не вижу ничего, что объясняет, как построить "объект аргумента" из C++. Есть свойство, называемое "аргументы", но оно, похоже, не заполнено, или я не понял, как его использовать.
1 ответ
Если мы посмотрим только на этот код JavaScript:
{
otherObject.Text = "Hello World";
setTimeout(function(otherObject) { otherObject.Text = "Goodbye World"; }, 9000 );
}
setTimeout говорят, что нужно ждать 9000, а затем вызывать анонимную функцию. Однако проблема в том, что анонимная функция имеет параметр. И функция setTimeout не знает, какой параметр передать функции.
<html>
<script>
var otherObject = 'Hello World';
setTimeout(function(otherObject){alert(otherObject);}, 1000);
</script>
</html>
Если вы попробуете этот код в chrome, он выдаст предупреждение undefined, потому что функция setTimeout не знает, что передать анонимной функции, она просто не передает аргументов.
Но если вы попробуете это:
<html>
<script>
var otherObject = 'Hello World';
setTimeout(function(){alert(otherObject);}, 1000);
</script>
</html>
Это предупредит Hello world, потому что теперь otherObject больше не является параметром для анонимной функции, а является локальной переменной, которая образует замыкание с анонимной функцией.
Таким образом, чтобы ваш код работал, функция setTimeout должна отличаться от функции setTimeout браузеров. Если вы хотите установить параметр для анонимной функции со стороны C++, вот что вы можете сделать:
QScriptValue setTimeout( QScriptContext* ctx, QScriptEngine* eng )
{
QScriptValue anonymous_callback = ctx->argument(0);
QScriptValue time = ctx->argument(1);
QThread::sleep(time.toInt32())
// Then Invoke the anonymous function:
QScriptValueList args;
otherObjectProto * otherObjectQtSide = new otherObjectProto();
otherObjectQtSide.setProperty("Text","Goodbye World!");
QScriptValue otherObject = engine->newQObject(otherObjectQtSide);// engine is pointer to the QScriptEngine instance
args << otherObject;
anonymous_callback.call(QScriptValue(),args);
}
Для простоты есть три вещи, которые я не включил:
OtherObjectProto не реализовано. Посмотрите здесь для примера.
QThread::sleep блокирует текущий поток, что может быть нежелательно, но его можно легко изменить, используя асинхронный QTimer.
engine-> newQObject имеет другие параметры, которые определяют владение QObject. Если вы не хотите утечки памяти, лучше прочитайте ее.