Wie bekomme ich Javascript in ein QWebView, um neue Instanzen von C++-basierten Klassen zu erstellen?

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

Frage

Ich habe erfolgreich ein C++-Objekt zu einem QWebFrame hinzugefügt mit addToJavaScriptWindowObjectund kann einen Slot dieses Objekts von JavaScript aufrufen.

Was ich aber wirklich möchte, ist, dass einer dieser Slots ein neues Objekt zurückgibt.Ich habe zum Beispiel einen Slot wie diesen, der eine von QObject abgeleitete Klasseninstanz zurückgibt:

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

Ich kann diesen Slot so erfolgreich über Javascript aufrufen

   var foo=myapp.helloWorld();

Aber Foo scheint leer zu sein, ich kann keine Slots aufrufen oder keine Eigenschaften davon von JavaScript aufnehmen.

Irgendwelche Ideen, wie ich das erreichen kann?

War es hilfreich?

Lösung

Eine ziemlich hässliche Hack, den ich in Betracht gezogen habe, ist addToJavaScriptWindowObject zu verwenden, um das Objekt, das ich mit einem zufälligen Namen in das Fenster Objekt zurückkehren will fallen, haben dann meinen Schlitz den Namen des Objektinstanz zurückgeben statt:

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

Die JS geschrieben werden kann, zu überprüfen, ob der Rückgabewert ein String ist, und wenn ja, aus dem Fenster das Objekt greifen.

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

Ein wenig hässlich, aber erhalte ich durch, bis eine bessere Methode kommt. Zukunft Qt-Versionen werden die Skriptunterstützung vereinen, so dass sie alle auf der Javascript in WebKit basiert, so hoffentlich wird dies verbessern dann!

Andere Tipps

Sie können Ihr Objekt Zeiger auf einen QObject * und zurück, dass zuweisen.

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

Das funktioniert für mich auf Qt Webkit-Port auf Linux.

QtScript hat die Vorstellung von Prototypen - die Sie einen C ++ Prototyp für einen Skript Wert erstellen kann. Wir untersuchen, ob wir QtScript mit Javascriptüberbrücken können - die sollte ergibt die Möglichkeit, auch Prototypen von WebKit JavaScript-Umgebung; http://doc.trolltech.com/ 4.5 / qtscript.html # Making-use-of-Prototyp-basierte Vererbung

Versuchen Sie, Ihr neues Objekt als QObject* und nicht als MyObject* zurückzugeben.Wenn Sie nur mit QtScript arbeiten, können Sie anrufen qScriptRegisterMetaType um etwas Code für die Konvertierung von MyObject*s in QScriptValues ​​(oder QVariants) zu definieren, aber es scheint kein Äquivalent für die in QtWebKit verwendete JavaScript-Engine zu geben.

Ärgerlicherweise bedeutet dies, dass die Offenlegung Ihres internen Objektmodells für WebKit entweder einen separaten Satz von Proxy-Funktionen erfordert, die Ihre Objektzeiger in QObject*s konvertieren, oder die Verwendung von Adapterklassen, um dasselbe zu tun.

Diese Antwort beruht auf Paulus 'Antwort, aber ein bisschen vereinfacht. Getestet und funktioniert für Qt 5.3. Sie benötigen eine Fabrik, die ein Objekt instanziiert, und gibt dann einen QObject Zeiger auf dieses Objekt. Die Objektklasse von QObject erben, so dass es richtig in JavaScript funktioniert:

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

Mit diesem können Sie die folgenden Aktionen von Javascript:

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

An diesem Punkt haben Sie sowie obj1 im globalen JavaScript-Namespace myobject (sie nur Zeiger sind, so die beiden folgenden Werke zu tun:

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

An dieser Stelle können Sie connect in JavaScript verwenden C ++ Signale zu JavaScript-Slots zu verbinden. Weitere Informationen zu dieser Technik hier: http://doc.qt.io/qt- 5 / QtWebKit-bridge.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top