如何使用QML QtWebView调用C++?

How to use QML QtWebView to call C++?

使用 Qt 5.5,使用 Minibrowser example they provide, it uses something different than QWebView widget. Instead, it uses QML and a QtWebView module。当您查看 Javascript 的 navigator.appVersion 时,它会让您知道 QWebView 加载了自定义的 AppleWebKit/538.1(Qt5.5 附带的东西),而 QtWebView(注意区别)加载本机核心 OS AppleWebKit/601.1.56。这是已确认的,因为当我在 OSX(El Capitan 版本)上加载 Safari 时,它显示 601.1.56.

然而,问题是我在 Minibrowser 中的 Javascript 函数如何调用后端的 C++ 函数来做更强大的事情?当我使用 QWebView 小部件时,我能够使用 C++ webkit bridge 让我注入 DOM 我的 C++ 对象,因此可以调用我的 C++ 代码。我没有看到关于如何使用 QtWebView 的基于 QML 的 Minibrowser 示例执行此操作的任何技术文档。有什么技巧?

编辑:哦,澄清一下,我不是通过网络服务器用它调用远程网页。我只是通过 file:// 调用东西。换句话说,我正在使用丰富的 webkit 界面给我一个超级强大的 GUI,它远远超出了 Qt 小部件和 QML 可以为我提供的功能。

我找到了答案。基本上,在 Qt5.5 中,我正在使用 QtWebView 进行试验。 class 方法大部分未记录在案,将来可能会更改。

目前,唯一的技术是消息传递,而不是原生 C++ class 方法调用,就像您可以在 QWebView C++ Bridge 中使用的那样。 QWebView C++ Bridge 仅适用于 QWebView 小部件,不适用于 QtWebView QML。因此,您使用 navigator.qt.postMessage() API 将此消息从 Javascript 传递到您的 QML,然后 QML 可以调用 C++。为了获得额外的功能,您需要执行几个步骤。这是一个例子:

Invoke C++ method from webviews Javascript

这里有一点博客:

http://rschroll.github.io/beru/2013/08/21/qtwebview.experimental.html

从示例中可以看出,您必须将这些导入添加到 main.qml:

import QtWebKit 3.0
import QtWebKit.experimental 1.0

然后,在您的 WebView{} 部分中,您必须添加这一行:

experimental.preferences.navigatorQtObjectEnabled: true

此时,您可以调用 navigator.qt.postMessage("call foo in C++"); 向 QML 发送消息,然后您可以在 WebView{} 部分中通过以下方式获取该消息:

experimental.onMessageReceived: { ...do something here in the QML... }

然后您的 QML 可以通过以下方式将消息传递回 Javascript:

experimental.postMessage("okay, I called foo in C++")

然后在您的 Javascript 中,您可以像这样添加一个事件侦听器:

navigator.qt.onmessage = function(ev) {

  $('BODY').prepend(ev.data); // since console.log() is not possible

}

至于如何让你的QML调用C++,这里有一个例子:

编辑:在 Qt 5.5 中使用 QtWebView 进行更多实验后,它在以下方面显得相当不稳定。 我不推荐在 5.5 中使用它——它还没有准备好迎接黄金时段。在 Qt 5.5 中,您最好暂时使用 QWebView 小部件,然后再迁移到 QtWebEngine下一个版本的 Qt 何时发布(Qt 5.6、5.7?)。

  • 默认情况下,它会为您提供一个您可能不想要的右键单击上下文菜单。有趣的是,如果你导入实验库然后在你的 QML 中设置这个 属性,你可以关闭它:experimental.preferences.navigatorQtObjectEnabled: true.

  • 默认情况下,HTML5 postMessage() API(HTML5 的本机)似乎不起作用,除非您启用 experimental.preferences.navigatorQtObjectEnabled: true.

  • 当您启用 experimental.preferences.navigatorQtObjectEnabled: true 时,如果您在某些 HTML 页面元素上启用它们,则滚动条会消失,复选框和单选按钮看起来非常时髦,并且弹出 select 列表框停止工作。

  • 当您双击页面时,页面会缩放。