如何使用 QML QtWebView 调用 C++?
Posted
技术标签:
【中文标题】如何使用 QML QtWebView 调用 C++?【英文标题】:How to use QML QtWebView to call C++? 【发布时间】:2015-11-20 00:56:26 【问题描述】:在 Qt 5.5 中,使用他们提供的 Minibrowser example,它使用了不同于 QWebView widget 的东西。相反,它使用 QML 和 QtWebView module。当您查看 javascript 的 navigator.appVersion
时,它会让您知道 QWebView 加载自定义 AppleWebKit/538.1(Qt5.5 附带的东西),而 QtWebView(注意区别)加载本机核心操作系统 AppleWebKit/601.1.56。这得到了证实,因为当我在我的 OSX(El Capitan 版本)上加载 Safari 时,它显示 601.1.56。
然而,问题是我在 Minibrowser 中的 Javascript 函数如何在后端调用 C++ 函数来做更强大的事情?当我使用 QWebView 小部件时,我能够使用C++ webkit bridge 让我将我的 C++ 对象注入到 DOM 中,因此可以调用我的 C++ 代码。我没有看到任何关于如何使用 QtWebView 的基于 QML 的 Minibrowser 示例执行此操作的技术。什么技术?
编辑:哦,澄清一下,我不是通过网络服务器调用远程网页。我只是通过 file:// 调用东西。换句话说,我使用丰富的 webkit 界面为我提供了一个超级强大的 GUI,它远远超出了 Qt 小部件和 QML 可以为我提供的功能。
【问题讨论】:
【参考方案1】:我找到了答案。基本上,在 Qt5.5 中,我正在使用 QtWebView 进入实验领域。类方法大部分没有记录,将来可能会发生变化。
目前,唯一的技术是消息传递,而不是您可以在QWebView C++ Bridge 中使用的本机 C++ 类方法调用。 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++,这里有一个例子:
https://***.com/a/17881019/105539
编辑:在 Qt 5.5 中使用 QtWebView 进行更多实验后,它在以下方面显得相当不稳定。 我不建议在 5.5 中使用它——它还没有为黄金时段做好准备。 在 Qt 5.5 中,您最好暂时使用 QWebView 小部件,然后在下一个版本的时候迁移到 QtWebEngine Qt 出来了(Qt 5.6、5.7?)。
默认情况下,它会为您提供您可能不想要的右键单击上下文菜单。有趣的是,如果您导入实验库,然后在 QML 中设置此属性,则可以将其关闭:experimental.preferences.navigatorQtObjectEnabled: true
。
默认情况下,除非您启用 experimental.preferences.navigatorQtObjectEnabled: true
,否则 HTML5 postMessage() API(HTML5 原生 API)似乎不起作用。
启用 experimental.preferences.navigatorQtObjectEnabled: true
后,如果您在某些 HTML 页面元素上启用滚动条,它们就会消失,复选框和单选按钮看起来非常时髦,并且弹出式选择列表框停止工作。
当你双击一个页面时,它会缩放它。
【讨论】:
@MrEricSir 我想你可能会感到困惑。我指的是 QtWebView 的文档记录很差,而不是 QWebView。 QtWebView 随 5.5 一起发布,并且仅使用本机 webkit API,这些 API 仅在 android、ios 和 OSX 上发布,而不是在 Windows 或 Linux 上发布。另一方面,QWebView 附带 5.5,但附带较旧(但仍然可用)的 webkit 版本。 @MrEricSir 另外,5.5 中的 QtWebView 似乎还不能使用——正如我上面解释的那样,东西坏了。所以,现在真的别无选择,只能使用 QWebView,它只能在 5.5 中工作,但不会超过 5.5,然后再迁移到 QtWebEngine。然而,关于 QtWebEngine 的坏消息是它使用 Chromium 而不是 Webkit 进行部署——一个胖安装——并且很可能不会让你在 Apple Store 中获得批准。 我尝试过但失败并显示错误消息:"QtWebKit.experimental" is not installed
。为什么会这样?我在 Windows 上使用 Qt 5.7.0。以上是关于如何使用 QML QtWebView 调用 C++?的主要内容,如果未能解决你的问题,请参考以下文章
QML 中基于 WebSockets 的 Qt WebView 和 WebChannel
如何在 Qt Quick 中将 QML 项目转换为相应的 C++ 项目