在QWebView中,是否可以从JavaScript调用C ++函数?

13

我在QWebView中加载了一个网页。我希望JavaScript能够调用我的应用程序中的函数,并返回一些字符串以供JavaScript动态显示。

使用QWebView是否可行?基本上,是否可能在C++应用程序和QWebView控件之间建立桥梁?

1个回答

14

这就是我最终的解决办法。我在我的头文件中声明了一个名为"JavaScriptBridge"的类,并带有一个Q_INVOKABLE方法。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,从语义上来说可能更清晰,该方法旨在从“外部”调用。 - Tamás Szelei
1
每次在 javaScriptWindowObjectCleared 上重新建立桥梁都会得到 +1。 - cod3monk3y

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接