2012-03-08 70 views
12

我有一个网页加载在一个QWebView。在那里,我想让JavaScript调用我的应用程序的功能。该函数然后会返回一些JavaScript可以动态显示的字符串。是否可以在QWebView中调用JavaScript中的C++函数?

可以使用QWebView完成吗?基本上,应用程序(使用C++)和QWebView控件之间是否可以有桥梁?

回答

13

这就是我最终这样做的结果。我在头文件中用Q_INVOKABLE方法声明了一个“JavaScriptBridge”类。 Q_INVOKABLE方法可以从JavaScript调用:

class DictionaryJavaScriptBridge : public QObject { 

    Q_OBJECT 

public: 

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

private: 

    DictionaryWidget* dictionaryWidget_; 

}; 

然后在我的.cpp文件,我创建了桥:

jsBridge_ = new DictionaryJavaScriptBridge(this); 

我听javaScriptWindowObjectCleared信号。这一步非常重要,因为WebKit是会加载一个新页面时,清除所有的JavaScript对象,所以你需要每次加回桥:

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

最后,在javaScriptWindowObjectCleared插槽中,我添加了JavaScript的桥梁:

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

现在从JavaScript,会有暴露的一个全球性的 “ehbridge” 对象。我可以调用它的方法,像一个正常的JavaScript对象(QT Qt的类型转换为JavaScript类型)

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

是100%准确,Q_INVOKABLE只是创建了一个插槽,这样你就可以动态调用任何类别的公共插槽。尽管如此,如果您使用Q_INVOKABLE,则该方法旨在用于从“外部”调用,但语义上可能更清晰。 – 2012-03-11 10:10:25

+1

+1用于每次在'javaScriptWindowObjectCleared'上重新建立桥接 – cod3monk3y 2013-04-16 18:00:59

相关问题