3

是否可以从 Java 脚本中调用 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++ 函数或仿函数,并使其不是作为对象的属性而是作为独立函数可用。

4

3 回答 3

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");
    

完毕!

于 2016-01-29T22:04:01.803 回答
2

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

于 2013-04-01T14:24:29.303 回答
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 引擎。

于 2013-03-27T21:57:57.110 回答