6

我已经使用 addToJavaScriptWindowObject 成功地将 C++ 对象添加到QWebFrame中,并且可以从 javascript 调用该对象上的插槽。

但我真正想做的是让其中一个插槽返回一个新对象。例如,我有一个像这样的插槽,它返回一个 QObject 派生类实例:

   MyObject* MyApp::helloWorld()
   {
          //MyObject is dervied from QObject
          return new MyObject();
   }

我可以像这样从javascript成功调用这个插槽

   var foo=myapp.helloWorld();

但是 foo 似乎是空的,我无法调用任何插槽或从 Javascript 访问其上的任何属性。

关于如何实现这一目标的任何想法?

4

5 回答 5

3

我考虑过的一个相当丑陋的技巧是使用 addToJavaScriptWindowObject 将我想要返回的对象放入具有随机名称的窗口对象中,然后让我的插槽返回对象实例的名称:

QString MyApp::helloWorld()
{
     //general a unique name for the js variable
     QString name=getRandomVariableName();

     //here's the object we want to expose to js
     MyObject* pReturn=new MyObject();

     //we make attach our object to the js window object    
     getWebFrame()->addToJavaScriptWindowObject(name, pReturn,
         QScriptEngine::ScriptOwnership);  

     //tell js the name we used
     return name;
}

可以编写JS来检查返回值是否为字符串,如果是则从窗口中抓取对象:

var foo=myapp.helloWorld();
if (typeof foo == "string")
{
    foo=window[foo];
}

有点难看,但会在更好的方法出现之前让我度过难关。未来的 Qt 版本将统一脚本支持,使其全部基于 WebKit 中的 JavaScriptCore,因此希望这会有所改善!

于 2009-06-03T20:31:39.063 回答
2

您可以将 Object 指针分配给 QObject * 并返回它。

    QObject * obj = new MyObject();
    return obj;

这在 Linux 上的 Qt Webkit 端口上对我有用。

于 2011-06-03T07:22:42.127 回答
1

QtScript 具有原型的概念——它允许您为脚本值创建 C++ 原型。我们正在研究是否可以将 QtScript 与 JavaScriptCore 连接起来——这应该会导致使用 WebKit 的 JavaScript 环境中的原型的可能性;http://doc.trolltech.com/4.5/qtscript.html#making-use-of-prototype-based-inheritance

于 2009-06-04T14:51:04.950 回答
1

尝试将新对象作为 QObject* 而不是 MyObject* 返回。如果您只是使用 QtScript,那么您可以调用qScriptRegisterMetaType来定义一些代码来处理将 MyObject*s 转换为 QScriptValues(或 QVariants),但似乎没有与 QtWebKit 中使用的 JavaScript 引擎等效的代码。

令人讨厌的是,这意味着将您的内部对象模型暴露给 WebKit 将涉及使用一组单独的代理函数将您的对象指针转换为 QObject*s,或者使用某种适配器类来做同样的事情。

于 2009-06-11T15:55:56.357 回答
0

这个答案是基于保罗的答案,但有点简化。经过测试并适用于 Qt 5.3。您需要一个实例化对象的工厂,然后返回QObject指向该对象的指针。对象的类必须继承自,QObject以便它在 JavaScript 中正常工作:

QObject * MyApp::createInstance(QString objname) {
    MyClass * obj = new MyClass(this);
    m_mainWindow->webView->page()->mainFrame()->addToJavaScriptWindowObject(objname, obj, QWebFrame::ScriptOwnership);
    return obj;
}

有了这个,您可以从 Javascript 执行以下操作:

var myobject = MyApp.createInstance("obj1");

此时,您在全局 JavaScript 命名空间中拥有obj1以及myobject(它们只是指针,因此执行以下两项工作:

myobject.testmethod();
obj1.testmethod();

此时,您可以connect在 JavaScript 中使用将 C++ 信号连接到 JavaScript 插槽。有关此技术的更多信息:http: //doc.qt.io/qt-5/qtwebkit-bridge.html

于 2015-10-05T04:55:14.447 回答