如何使用QJSEngine构建API? [英] How to build an API with QJSEngine?

查看:261
本文介绍了如何使用QJSEngine构建API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从Qt开始,我的一个项目是使用QJSEngine来评估javascript,我想为脚本提供一个完整的API,包括类和全局函数。

I am starting with Qt and one of my projects is using QJSEngine to evaluate javascript and I want to provide an entire API to the script, with classes and global functions.

现在我的程序只提供ECMAScript默认的东西(eval,encodeURI,parseInt等等),但我需要向代码公开一些自定义类,比如浏览器API(WebSocket类,Image类,文档对象) )。例如:

Right now my program provides only the ECMAScript default stuff (eval, encodeURI, parseInt, etc...), but I need to expose some custom classes to the code, like the browsers API (WebSocket class, Image class, document object). For example:

var obj = new CustomClass("", 0);
var ret = obj.customClassMethod("[...]!");
customFunction(ret);

我需要在C ++中定义类的行为,它无助于评估类的定义让用户代码运行。

I need to define the behavior of the classes in C++, it wouldn't help evaluate the classes definition and let the user code run.

推荐答案

QScriptEngine 相比,如果使用 QObject 继承自定义类,可以添加自定义类Q_SCRIPT_DECLARE_QMETAOBJECTrel =nofollow noreferrer> Q_SCRIPT_DECLARE_QMETAOBJECT 宏, QJSEngine 不直接提供此功能。

In contrast to QScriptEngine, where you can add custom classes if they inherit from QObject by using the Q_SCRIPT_DECLARE_QMETAOBJECT macro, the QJSEngine does not directly provide this functionality.

您仍然可以使用Qt元对象系统为Javascript提供接口,但您必须在C ++中实例化该对象并将其添加到Javascript上下文中。
那么它的插槽,用 Q_INVOKABLE 定义的方法,以及用 Q_PROPERTY 定义的属性都可以从Javascript运行时。

You can still use the Qt Meta-object system to provide interfaces for Javascript, but you have to instantiate the object in C++ and add it to the Javascript context. Then it's slots, methods defined with Q_INVOKABLE, and properties defined with Q_PROPERTY are all accessible from within the Javascript runtime.

现在您可以创建一个工厂,为给定的<$创建自定义类 CustomClass 的实例c $ c> QJSEngine 包装为Javascript对象:

Now you can create a factory which creates instances of your custom class CustomClass for a given QJSEngine wrapped as Javascript objects:

class CustomClassFactory : public QObject
{
    Q_OBJECT
public:
  CustomClassFactory(QJSEngine* engine) : m_engine(engine) {}
  Q_INVOKABLE QJSValue createInstance() {
      // The engine takes ownership and destroys the object if no longer required.
      return m_engine->newQObject(new CustomClass());
  }
private:
    QJSEngine* m_engine;
}

需要构建工厂实例并将其添加到Javascript的全局对象中运行时:

A factory instance needs to be constructed and added to the global object of the Javascript runtime:

QJSEngine engine;
QJSValue factoryObj = engine.newQObject(new CustomClassFactory());
engine.globalObject().setProperty("_customClassFactory", factoryObj);

现在我们可以用Javascript构建对象:

Now we can construct objects in Javascript with:

var obj = _customClassFactory.createInstance()

当我们走到这一步时,让我们另外将自定义类的构造函数注入Javascript运行时:

As we've come this far, lets additionally inject a constructor for the custom class into the Javascript runtime:

QJSEngine engine;
// Again, the QJSEngine will take ownership of the created object.
QJSValue factoryObj = engine.newQObject(new CustomClassFactory());
engine.globalObject().setProperty("_customClassFactory", factoryObj);
engine.evaluate(
    "function CustomClass() {"
    "    return _customClassFactory.createInstance()"
    "}");

Etvoilà,现在你可以在Javascript中构建C ++对象,就像你自定义Javascript类一样:

Et voilà, now you can construct C++ object in Javascript, like you would custom Javascript classes:

var obj = new CustomClass()

对于上面提到的 WebSocket API,你可以包装 QtWebSocket 为此目的 - 这正是我提出建议方法时所需要的。

For the mentioned WebSocket API you could wrap QtWebSocket for that purpose – that was exactly what I required when I came up with the proposed approach.

请注意,为了简单起见,我省略了构造函数的参数,但是也可以简单地添加。

Note that for the sake of simplicity I omitted parameters for the constructor, but they can simply be added as well.

PS:我会添加更多官方文档的链接,但由于缺乏声誉,我不允许。

PS: I would have added more links to the official documentation, but due to the lack of reputation I'm not allowed to.

这篇关于如何使用QJSEngine构建API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆