2012-03-08 16 views
12

Tengo una página web cargada en un QWebView. Allí, me gustaría que JavaScript llame a una función de mi aplicación. Esa función devolvería algunas cadenas que JavaScript mostraría dinámicamente.¿Es posible llamar a una función C++ desde JavaScript en un QWebView?

¿Se puede hacer utilizando QWebView? Básicamente, ¿es posible tener algún puente entre la aplicación (en C++) y el control QWebView?

Respuesta

13

Así es como terminé haciéndolo. Decidí una clase "JavaScriptBridge" en mi archivo de encabezado con un método Q_INVOKABLE. Q_INVOKABLE métodos pueden ser llamados desde JavaScript:

class DictionaryJavaScriptBridge : public QObject { 

    Q_OBJECT 

public: 

    DictionaryJavaScriptBridge(DictionaryWidget* dictionaryWidget); 
    Q_INVOKABLE QStringList sentences(QString characters); 

private: 

    DictionaryWidget* dictionaryWidget_; 

}; 

Luego, en mi archivo .cpp, puedo crear el puente:

jsBridge_ = new DictionaryJavaScriptBridge(this); 

y escucho a la señal javaScriptWindowObjectCleared. Este paso es importante porque WebKit va a borrar todos los objetos de JavaScript al cargar una nueva página, por lo que deberá volver a agregar el puente cada vez que:

connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(mainFrame_javaScriptWindowObjectCleared())); 

Por último, en la ranura javaScriptWindowObjectCleared, agrego el puente JavaScript :

void DictionaryWidget::mainFrame_javaScriptWindowObjectCleared() { 
    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("ehbridge", jsBridge_); 
} 

Ahora, desde JavaScript, habrá un objeto global "ehbridge" expuesto. Puedo llamar a sus métodos como un objeto normal de JavaScript (Qt convierte los tipos de Qt a tipos de JavaScript)

var sentences = ehbridge.sentences("test"); 
+1

Para ser fiable al 100%, Q_INVOKABLE sólo crea una ranura, por lo que puede invocar dinámicamente cualquier ranura pública de cualquier clase. Aún así, podría ser más claro semánticamente si está usando Q_INVOKABLE que el método está destinado a llamar desde "afuera". –

+1

+1 para restablecer el puente cada vez en 'javaScriptWindowObjectCleared' – cod3monk3y

Cuestiones relacionadas