Comment obtenir Javascript dans un QWebView pour créer de nouvelles instances de classes basées sur C++ ?

StackOverflow https://stackoverflow.com/questions/943554

Question

J'ai ajouté avec succès un objet C++ à un QWebFrame avec addToJavaScriptWindowObject, et peut appeler une fente sur cet objet de JavaScript.

Mais ce que je veux vraiment faire, c'est qu'un de ces emplacements renvoie un nouvel objet.Par exemple, j'ai un slot comme celui-ci, qui renvoie une instance de classe dérivée de QObject :

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

Je peux appeler ce slot depuis javascript avec succès comme ceci

   var foo=myapp.helloWorld();

Mais FOO semble être vide, je ne peux pas appeler des emplacements ou accéder à des propriétés à partir de JavaScript.

Des idées sur la façon dont je peux y parvenir ?

Était-ce utile?

La solution

Un assez laid bidouille je l'ai considéré est d'utiliser addToJavaScriptWindowObject de laisser tomber l'objet que je veux retourner dans l'objet de la fenêtre avec un nom aléatoire, alors ma fente retourne le nom de l'instance d'objet à la place:

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

Les JS peuvent être écrites pour vérifier si la valeur de retour est une chaîne, et si elle est, saisir l'objet de la fenêtre.

var foo=myapp.helloWorld();
if (typeof foo == "string")
{
    foo=window[foo];
}

Un peu moche, mais je vais me débrouiller jusqu'à ce qu'une meilleure méthode se présente. Les versions futures de Qt vont unifier le support de script pour que tout est basé sur le JavaScriptCore dans WebKit, alors je espère que cela améliorera alors!

Autres conseils

Vous pouvez attribuer le pointeur de votre objet à un QObject * et le retourner.

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

qui fonctionne pour moi sur le port Qt Webkit sur Linux.

QtScript a la notion de prototypes - ce qui vous permet de créer un prototype C ++ pour une valeur de script. Nous enquêtons wether nous pouvons combler QtScript avec JavaScriptCore - qui devrait entraîner la possibilité d'utiliser des prototypes de l'environnement JavaScript de WebKit ainsi; http://doc.trolltech.com/ 4,5 / qtscript.html # making-usage de base-prototype héritage

Essayez de renvoyer votre nouvel objet en tant que QObject* plutôt qu'en MyObject*.Si vous travaillez uniquement avec QtScript, vous pouvez appeler qScriptRegisterMetaType pour définir du code pour gérer la conversion des MyObject* en QScriptValues ​​(ou QVariants), mais il ne semble pas y avoir d'équivalent pour le moteur JavaScript utilisé dans QtWebKit.

Malheureusement, cela signifie que l'exposition de votre modèle d'objet interne à WebKit impliquera soit d'avoir un ensemble distinct de fonctions proxy qui convertissent vos pointeurs d'objet en QObject*, soit d'utiliser des classes d'adaptateur d'une certaine sorte pour faire la même chose.

Cette réponse est basée sur la réponse de Paul, mais un peu simplifié. Testé et travailler pour Qt 5.3. Vous avez besoin d'une usine qui instancie un objet, puis renvoie un pointeur QObject à cet objet. La classe de l'objet doit hériter de QObject pour qu'il fonctionne correctement en JavaScript:

QObject * MyApp::createInstance(QString objname) {
    MyClass * obj = new MyClass(this);
    m_mainWindow->webView->page()->mainFrame()->addToJavaScriptWindowObject(objname, obj, QWebFrame::ScriptOwnership);
    return obj;
}

Avec cela, vous pouvez effectuer les opérations suivantes de Javascript:

var myobject = MyApp.createInstance("obj1");

À ce stade, vous avez obj1 ainsi que myobject dans l'espace de nommage global JavaScript (ils ne sont que des pointeurs, ce faisant, les deux ouvrages suivants:

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

À ce stade, vous pouvez utiliser connect en JavaScript pour connecter les signaux C de slots à JavaScript. Plus d'informations sur cette technique: http://doc.qt.io/qt- 5 / QtWebKit-bridge.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top