1

我想从 c++ 执行一个匿名 Qt 脚本函数,但无法确定要使用的 QScriptContext。

这是脚本:

{
  otherObject.Text = "Hello World";
  setTimeout(function(otherObject) { otherObject.Text = "Goodbye World"; }, 9000 );
}

这是 c++ 中的 setTimeout 方法:

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++ 构建“参数对象”的内容。有一个属性叫“arguments”但是好像没有填写,或者我还没想好怎么用。

4

1 回答 1

2

如果我们只看这个 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);
}

为简单起见,我没有包括三件事:

  1. otherObjectProto 未实现。看这里的例子。

  2. QThread::sleep 正在阻塞当前线程,这可能不是我们所希望的,但可以很容易地使用 QTimer 将其修改为异步。

  3. engine->newQObject 还有其他参数,定义了 QObject 的所有权,如果你不想内存泄漏,最好读一下。

于 2013-04-05T11:19:20.493 回答