代码之家  ›  专栏  ›  技术社区  ›  Paul Dixon

如何在QWebVIEW中获取JavaScript来创建基于C++的类的新实例?

  •  6
  • Paul Dixon  · 技术社区  · 15 年前

    我已经成功地将一个C++对象添加到一个QWebFrror中 addToJavaScriptWindowObject , 并且可以从JavaScript调用那个对象上的一个槽。

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

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

    我可以像这样成功地从JavaScript调用这个时隙。

       var foo=myapp.helloWorld();
    

    但是Foo似乎是空的,我不能调用任何时隙或访问任何 属性。

    我有什么办法可以做到这一点?

    5 回复  |  直到 8 年前
        1
  •  4
  •   Paul Dixon    15 年前

    我考虑过的一个相当难看的方法是使用addtojavascriptwindowobject将要返回的对象以随机名称放入window对象,然后让slot返回对象实例的名称:

    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,所以希望这将改进!

        2
  •  2
  •   Chandan    13 年前

    可以将对象指针分配给QObjult*并返回该对象指针。

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

    这对我在linux上的qt webkit端口是有效的。

        3
  •  1
  •   Henrik Hartz    15 年前

    QtScript有原型的概念,它允许你为脚本值创建一个C++原型。我们正在研究我们可以用JavaScript内核来桥接QtScript。 应该 结果也可能使用webkit的javascript环境中的原型; http://doc.trolltech.com/4.5/qtscript.html#making-use-of-prototype-based-inheritance

        4
  •  1
  •   Rob Knight    15 年前

    尝试将新对象返回为qobject*而不是myobject*。如果你只是和QtScript一起工作,那么你可以打电话 qScriptRegisterMetaType 定义一些代码来处理将myobject*s转换为qscriptvalues(或qvariants)的过程,但是对于qtwebkit中使用的javascript引擎似乎没有等效的代码。

    令人恼火的是,这意味着向webkit公开您的内部对象模型将涉及使用一组单独的代理函数将对象指针转换为qobject*s,或者使用某种适配器类来执行相同的操作。

        5
  •  0
  •   Michael F    9 年前

    这个答案是基于保罗的答案,但有点简单。为Qt5.3测试和工作。您需要一个工厂来实例化一个对象,然后返回 QObject 指向此对象的指针。对象的类必须继承自 QObjor 以便它在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");
    

    在这一点上,你已经 obj1 以及 myobject 在全局javascript命名空间中(它们只是指针,因此执行以下两项工作:

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

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