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");
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 para restablecer el puente cada vez en 'javaScriptWindowObjectCleared' – cod3monk3y