Come ottenere il codice Javascript in una QWebView per creare nuove istanze di C++ classi di base?

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

Domanda

Ho aggiunto un oggetto C++ per un QWebFrame con addToJavaScriptWindowObject, e possibile chiamare una fessura su un oggetto da javascript.

Ma quello che voglio fare è di avere una di quelle slot restituisce un nuovo oggetto.Per esempio, ho uno slot come questo, che restituisce un QObject classe derivata esempio:

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

Posso chiamare questa slot da javascript con successo come questo

   var foo=myapp.helloWorld();

Ma pippo sembra essere vuoto, non posso chiamare qualsiasi slot o accedere a qualsiasi le proprietà da Javascript.

Tutte le idee su come posso realizzare questo?

È stato utile?

Soluzione

Un piuttosto brutto mod Ho considerato è quello di utilizzare addToJavaScriptWindowObject far cadere l'oggetto voglio tornare nell'oggetto finestra con un nome casuale, quindi il mio slot per restituire il nome dell'istanza oggetto invece:

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

I JS possono essere scritti per verificare se il valore di ritorno è una stringa, e se lo è, afferrare l'oggetto dalla finestra:.

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

Un po 'brutto, ma mi metterò da parte fino a quando un metodo migliore viene avanti. Le future versioni di Qt stanno andando unificare il supporto per gli script in modo che sia tutto basato sul JavaScriptCore in WebKit, quindi spero che questo migliorerà allora!

Altri suggerimenti

È possibile assegnare il puntatore ad un oggetto QObject * e restituire questo.

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

che sta lavorando per me sulla porta Qt Webkit su Linux.

QtScript ha la nozione di prototipi - che permette di creare un prototipo C ++ per un valore di script. Stiamo indagando scendessimo possiamo colmare QtScript con JavaScriptCore - che dovrebbe comportare la possibilità di utilizzare prototipi da ambiente JavaScript da parte di WebKit pure; http://doc.trolltech.com/ 4.5 / qtscript.html # making-uso-di-prototipo a base-eredità

Provare a ripristinare il vostro nuovo oggetto come QObject* piuttosto che un MyObject*.Se stai lavorando con QtScript, allora si può chiamare qScriptRegisterMetaType per definire un po ' di codice per la gestione di conversione di MyObject* * * * s in QScriptValues (o QVariants), ma non sembra essere un equivalente per il motore JavaScript utilizzato in QtWebKit.

Fastidiosamente, questo significa che esporre l'interno del modello di oggetto di WebKit coinvolgerà avendo un set di funzioni di proxy che convertire i puntatori a oggetti di QObject*s, o utilizzare un adattatore per classi di qualche tipo per fare la stessa cosa.

Questa risposta si basa sulla risposta di Paolo, ma un po 'semplificato. Testato e funzionante per Qt 5.3. Hai bisogno di una fabbrica che crea un'istanza di un oggetto, e quindi restituisce un puntatore QObject a questo oggetto. classe dell'oggetto deve ereditare da QObject in modo che funzioni correttamente in JavaScript:

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

Con questo, è possibile effettuare le seguenti operazioni da JavaScript:

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

A questo punto, si hanno obj1 così come myobject nel namespace globale JavaScript (sono solo puntatori, così facendo entrambe le seguenti opere:

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

A questo punto, è possibile utilizzare connect in JavaScript per connettere i segnali C ++ per slot JavaScript. Maggiori informazioni su questa tecnica qui: http://doc.qt.io/qt- 5 / QtWebKit-bridge.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top