Comment construire une API avec QJSEngine?

Je commence avec Qt et l’un de mes projets utilise QJSEngine pour évaluer le javascript et je souhaite fournir une API complète au script, avec des classes et des fonctions globales.

Actuellement, mon programme ne fournit que les éléments par défaut ECMAScript (eval, encodeURI, parseInt, etc …), mais je dois exposer certaines classes personnalisées au code, telles que l’API des navigateurs (classe WebSocket, classe Image, document). Par exemple:

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

Je dois définir le comportement des classes en C ++, cela n’aiderait pas à évaluer la définition des classes et à laisser le code utilisateur s’exécuter.

Contrairement à QScriptEngine , qui permet d’append des classes personnalisées si elles héritent de QObject à l’aide de la macro Q_SCRIPT_DECLARE_QMETAOBJECT , QJSEngine ne fournit pas directement cette fonctionnalité.

Vous pouvez toujours utiliser le système de méta-objects Qt pour fournir des interfaces pour Javascript, mais vous devez instancier l’object en C ++ et l’append au contexte Javascript. Ensuite, il y a les slots, les méthodes définies avec Q_INVOKABLE et les propriétés définies avec Q_PROPERTY sont accessibles depuis le moteur d’exécution Javascript.

Vous pouvez maintenant créer une fabrique qui crée des instances de votre classe personnalisée CustomClass pour un QJSEngine donné, enveloppé sous forme d’objects Javascript:

 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; } 

Une instance d’usine doit être construite et ajoutée à l’object global du runtime Javascript:

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

Nous pouvons maintenant construire des objects en Javascript avec:

 var obj = _customClassFactory.createInstance() 

Comme nous sums arrivés jusque-là, ajoutons un constructeur pour la classe personnalisée au runtime Javascript:

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

Et voilà, vous pouvez maintenant construire un object C ++ en Javascript, comme vous le feriez avec des classes Javascript personnalisées:

 var obj = new CustomClass() 

Pour l’API WebSocket mentionnée, vous pouvez QtWebSocket à cet effet – c’est exactement ce que je QtWebSocket lorsque j’ai proposé l’approche proposée.

Notez que par souci de simplicité, j’ai omis les parameters du constructeur, mais ils peuvent aussi être simplement ajoutés.

PS: J’aurais ajouté plus de liens à la documentation officielle, mais en raison du manque de réputation, je ne suis pas autorisé à le faire.

Si vous consultez la documentation de QScriptEngine ou en cherchant des “exemples de QScriptEngine”, vous trouverez des informations sur la création de classes personnalisées C ++ disponibles pour QScriptEngine.

Voici un bon sharepoint départ: lien vers exemple

QScriptEngine est très similaire à QJsEngine, donc cela ne devrait pas être un gros problème pour vous.

J’espère que cela t’aides 🙂