Qt 5.0:向 Javascript 公开 C++ 方法
Posted
技术标签:
【中文标题】Qt 5.0:向 Javascript 公开 C++ 方法【英文标题】:Qt 5.0: Exposing C++ methods to Java Script 【发布时间】:2013-01-18 09:54:40 【问题描述】:我尝试将一个对象作为全局属性公开给具有以下方法的 Java Script:
Q_INVOKABLE MyObject* createMyObject();
MyObject 派生自 QObject。
当我在 Java Script 中调用此方法时,它会返回一个对象类型:
QVariant(MyObject*)
我想知道是否可以自动将其转换为 QJSValue 以便我可以在脚本中进一步使用它?
【问题讨论】:
【参考方案1】:似乎 Java Script 使用 QVariant 作为任何“未知”类型的不透明包装器。该值可以很容易地传递,但不能使用它的任何属性,也不能调用它的任何方法。要在脚本中使用,它应该转换为 QJSValue。我发现的唯一方法是像这样声明辅助函数:
Q_INVOKABLE QJSValue convert(QVariant var)
return _engine.newQObject(var.value<QObject*>());
那么就可以将 QVariant 转换为 QJSValue:
var obj = convert(createMyObject());
并且 obj 将是类型
MyObject
所以现在可以在脚本中使用了。
【讨论】:
很好的解决方案。会注意的:)。 一段时间后找到了更正确的解决方案(使用 qmlRegisterType)。请参阅我最近的回答。【参考方案2】:所有需要做的就是在脚本中引用 MyObject 之前在某处调用下面的方法。
qmlRegisterType<MyObject>("", 1, 0, "MyObject");
然后 createMyObject 方法将返回正确的类型,无需任何转换:
var obj = createMyObject();
MyObject
其实如果我们改变下面方法的类型
Q_INVOKABLE MyObject* createMyObject();
到
Q_INVOKABLE QObject* createMyObject();
即使没有它也会开始工作
qmlRegisterType
【讨论】:
令人惊讶的是!我不使用 qml,它适用于 qmlRegisterType 而不适用于 qRegisterMetaType。【参考方案3】:你可以使用QJSEngine::newQObject()
方法。
使用newQObject() 来包装一个QObject(或子类)指针。 newQObject() 返回一个代理脚本对象; QObject 的属性、子项以及信号和槽可用作代理对象的属性。不需要绑定代码,因为它是使用 Qt 元对象系统动态完成的。
请在QJSEngine Class: QObject Integration阅读更多详情。
【讨论】:
是的,我知道。但它需要我类中每个 Q_INVOKABLE 的包装器才能将返回值转换为 QJSValue。【参考方案4】:我处于类似情况,尝试使用 QJSEngine 编写脚本(目前卡在尝试将 QList 暴露给 QJSEngine...)
我认为将现有 C++ 对象公开给脚本的最简单方法如下:
//create c++ file object
MyObject* anObject = new MyObject();
//make c++ object available to script
QJSValue scriptObject = myEngine.newQObject(anObject);
myEngine.globalObject().setProperty("obj", scriptObject);
您现在应该可以从脚本访问“obj”了。
顺便问一下,如何找出脚本中的类型(QVariant(MyObject*))?
【讨论】:
以上是关于Qt 5.0:向 Javascript 公开 C++ 方法的主要内容,如果未能解决你的问题,请参考以下文章
串行 Hexa 对话框(C++/Qt 5.0 的 python 代码)
ATL ActiveX 控件如何向 javascript 公开布尔值