¿Cómo obtener Javascript en QWebView para crear nuevas instancias de clases basadas en C++?

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

Pregunta

Agregué exitosamente un objeto C++ a un QWebFrame con agregarToJavaScriptWindowObject, y puede llamar a una ranura en ese objeto de JavaScript.

Pero lo que realmente quiero hacer es que una de esas ranuras devuelva un objeto nuevo.Por ejemplo, tengo una ranura como esta, que devuelve una instancia de clase derivada de QObject:

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

Puedo llamar a esta ranura desde javascript con éxito de esta manera

   var foo=myapp.helloWorld();

Pero Foo parece estar vacío, no puedo llamar a ninguna ranura ni acceder a ninguna propiedad desde JavaScript.

¿Alguna idea sobre cómo puedo lograr esto?

¿Fue útil?

Solución

Un truco bastante feo he considerado es el uso de addToJavaScriptWindowObject a soltar el objeto Quiero volver a la ventana de objeto con un nombre aleatorio, y luego tener mi ranura para devolver el nombre de la instancia del objeto en su lugar:

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

Los JS pueden ser escritos para comprobar si el valor de retorno es una cadena, y si lo es, agarrar el objeto desde la ventana:.

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

Un poco feo, pero me llevará hasta por un método mejor que venga. Versiones futuras de Qt van unificar el soporte de scripting para que todo se basa en la JavaScriptCore en WebKit, y espero que esto mejorará entonces!

Otros consejos

Puede asignar el puntero del objeto a un QObject * y devolver eso.

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

Esto es trabajo para mí en el puerto Qt Webkit en Linux.

QtScript tiene la noción de prototipos - que le permite crear un prototipo C ++ para un valor guión. Estamos investigando si podríamos hacer un puente con QtScript JavaScriptCore - que debe como resultado la posibilidad de utilizar prototipos de entorno JavaScript de WebKit así; http://doc.trolltech.com/ 4,5 / qtscript.html # confección de uso de la basado en prototipos-herencia

Intente devolver su nuevo objeto como QObject* en lugar de MyObject*.Si solo estás trabajando con QtScript, entonces puedes llamar qScriptRegisterMetaType para definir algún código para manejar la conversión de MyObject*s en QScriptValues ​​(o QVariants), pero no parece haber un equivalente para el motor JavaScript utilizado en QtWebKit.

De manera molesta, esto significa que exponer su modelo de objetos interno a WebKit implicará tener un conjunto separado de funciones de proxy que conviertan los punteros de sus objetos a QObject*s, o usar clases de adaptador de algún tipo para hacer lo mismo.

Esta respuesta se basa en la respuesta de Pablo, pero un poco simplificada. Probado y trabajando para Qt 5.3. Se necesita una fábrica que crea la instancia de un objeto, y luego devuelve un puntero QObject a este objeto. la clase del objeto tiene que heredar de QObject para que funcione correctamente en JavaScript:

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

Con esto, usted puede hacer lo siguiente de Javascript:

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

En este punto, se han obj1, así como myobject en el espacio de nombres global JavaScript (que son sólo sugerencias, por lo tanto haciendo de las siguientes obras:

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

En este punto, se puede utilizar en connect JavaScript para conectar las señales de C ++ para ranuras de JavaScript. Más información sobre esta técnica aquí: http://doc.qt.io/qt- 5 / QtWebKit-bridge.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top