可以从Java Script中调用QObject

时间:2013-02-28 17:09:07

标签: qt qml qt5 qt-quick qtquick2

是否可以从Java Script中调用QObject? 我的意思是注册QObject派生类实例,如下所示:

QObject* obj = new MyObject();
QJSValue js_value = js_engine.newQObject(obj);

js_engine.globalObject().setProperty("myFunction", js_value);

然后能够从Java Script

调用 myFunction
myFunction()

环境:Qt 5.0.1

编辑:此操作的主要目的是在Java脚本引擎中注册C ++函数或仿函数,并使其不作为对象的属性使用,而是作为独立函数使用。

3 个答案:

答案 0 :(得分:4)

我认为不可能直接从C ++向QJSEngine globalObject添加函数。虽然这个技巧有效:

  1. 使用要向QJSEngine公开的Q_INVOKABLE函数定义基于QObject的类。

    class MyObject : public QObject 
    {
        Q_OBJECT
    public:
        Q_INVOKABLE int myFunction(int x) 
        {
            return x + 3;
        }
    };
    
  2. 创建此对象的实例并从C ++定义其父对象。 (为您的对象实例定义父级非常重要。如果没有父级,QJSEngine会认为它拥有该对象并可以将其删除!)

    MyObject *obj = new MyObject();
    obj->setParent(QCoreApplication::instance());
    
  3. 将您的对象暴露给QJSEngine。

    js_engine.globalObject().setProperty("myObject", js_engine.newQObject(obj));
    
  4. 将对象的函数从JavaScript传输到全局对象。

     engine.evaluate("this.myFunction = myObject.myFunction");
    
  5. 从JavaScript环境中删除myObject。

     engine.evaluate("delete myObject");
    
  6. 完成!

答案 1 :(得分:2)

我花了太多时间试图做同样的事情。现在我99.9%肯定没有可能用当前的Qt版本(5.0.1)做到这一点。

答案 2 :(得分:1)

如果您使用的是Qt5,您可以使用:

QObject* obj = new MyObject();
js_engine.globalObject().setProperty("myFunction", js_engine.toScriptValue(&obj::myFunction));

并且你需要你的QObject派生类在必须公开的每个方法上都有Q_OBJECT宏和Q_INVOKABLE

如果您使用的是QML,最好使用QQmlContext::setContextObject

youQmlContext.setContextObject(new MyObject());

因此,MyObject类的所有Q_PROPERTY,Q_INVOKABLE和Q_SLOT成员都可以作为上下文本身的成员用于QML / JS引擎。