QtWebkits如何向QtWebEngine过渡

QtWebkits如何向QtWebEngine过渡

1. 前言

很遗憾,QtWebkits在Qt5.6以上版本被淘汰了,对于这个接口良且和其余类例如QWebFrame完美结合的组件就这么没了,我只能表示可惜。对于QtWebEngine新的组件,不得不认可它从Chromium继承过来的强大的性能,但接口上还不是很丰富,和其余类的交互也不是很完美,期待Qt可以对其进行进一步开发,我也会不断的升级Qt,尝试新的接口。javascript

目前而言,QWebEngine有如下缺点:html

  • MinGW版本的Qt不支持,即使是Qt5.6版本以上也是不支持的。仅仅支持MSVC版本。
  • 接口暂时不丰富
  • 没法和QWebFrame进行交互(使用了新的QWebChannel和QWebEnginePage组合进行交互)

基于咱们的GPS定位项目,参考:[Qt开发北斗定位系统融合百度地图API及Qt程序打包发布] ,咱们在该项目中使用的是Qt5.5版本,在嵌入的浏览器做为加载地图用的是QWebKits组件,咱们将其升级使用QWebEngine进行加载地图,和HTML和JS进行交互。咱们以此为例,进行简要的介绍。java

2. 二者的UI上面的区别

你刚刚升级到Qt5.6版本可能在UI设计界面时候在组件中找不到QWebEngineView这个组件,没法从这里拖拽这个组件到你的UI界面上。我查阅了不少资料,看到别人常用 ui->webEngineview->...这样,我甚至怀疑是否由于安装了其余版本的Qt影响到了我,我卸载了包含5.6版本的全部Qt,又从新安装了一遍,可是再重启软件后,依然没有发现QWebEngineView这个鬼东西。在Qt5.5中你也能发现有这样的组件QWebView,如图1所示:c++

Qt旧版本中的WebKits项

QWebView组件能够经过QWebFrame来进行HTML和JS的通讯,若是过渡到QWebEngineView,要是没有这个UI组件的话,我如何把浏览器嵌入到软件界面,实现网页和软件的混合编程呢。根据官方提供的一个例子中,cookiebrowser中找到了答案,这也是官方给的例子中,惟一一个嵌入到网页中的!(不得不说,Qt给的例子很模糊不好!) 通过研究, QWebEngineView使用widget组件,拖拉出来是一个透明的组件,对着组件按右键->promote to.. ->选择QWebEngineView,如图2,完成操做。程序员

把Widget promote to 成QWebEngineView组件

有了QWebEngineView这个UI组件,咱们能够在程序中调用其成员、方法和函数完成操做了。web

3. 使用方法区别

在使用方法上有很大的区别,能够说是两个彻底不一样理念的东西,这里为了更通俗易懂,就不粘贴API文档中函数解释,就用最经常使用的!编程

#include <QtWebEngineWidgets>   // 基本组件
#include <QWebEnginePage>       // HTML页面
#include <QWebChannel>          // C++和JS/HTML双向通讯,代替了已淘汰的QtWebFrame的功能

在咱们的项目中一开始就要引入这样的组件,但在咱们的项目中,没有频繁用到与JS的互相交互,因此这里暂时没有关于QWebChannel的使用方法,只留下这个接口。浏览器

如下为区别:cookie


  • 在WebKits中的初始化:
QUrl url(strMapPath);       // strMapPath为QString类,是你html文件的路径
ui->webView->load(url);
ui->webView->setContentsMargins(0,0,0,0);
ui->webView->setTextSizeMultiplier(1);//设置网页字体大小
connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
            this, SLOT(slotPopulateJavaScriptWindowObject()));

咱们会使用load方法加载html所在的界面,使用QWebFrame类的mainFrame()中的SIGNAL和槽函数函数

void Widget::slotPopulateJavaScriptWindowObject()
{
    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("ReinforcePC", this);
}

进行响应。参考文献1:《javascript调用qt》,能够解释这个槽函数的重要性。

  • 在WebEngine中的初始化:
QWebEnginePage *page = new QWebEnginePage(this);  // 定义一个page做为页面管理
QWebChannel *channel = new QWebChannel(this);     // 定义一个channel做为和JS或HTML交互
page->load(strMapPath);                         // page上加载html路径
page->setWebChannel(channel);                   // 把channel配置到page上,让channel做为其信使
ui->webEngine->setPage(page);                   // 创建page和UI上的webEngine的联系

若是你的 初始化程序写到这里,当你运行程序的时候,不管是webKits里的WebView仍是新版的webEngineView,你的UI界面上的那个组件区域就会显示那个html文件了。

到此,咱们完成了二者的初始化。


  • WebKits组件中的运行JS:

咱们以按钮的槽函数为例,当点击按钮时,会向JS发送命令,运行JS脚本,咱们这里发送的是将显示变为卫星图的JS命令:

void Widget::on_pushButtonStreetMap_clicked()
{
    QWebFrame *frame = ui->webView->page()->mainFrame(); // 定义一个QWebFrame负责交互
    QString cmd = QString("showStreetMap()"); // JS的命令
    frame->evaluateJavaScript(cmd);           // 使用frame下的命令运行该命令
}

从这个例子中咱们也能够看到,QWebFrame是JS交互的关键。

  • WebEngine组件中的运行JS:

仍是以该槽函数为例:

void Widget::on_pushButtonSatelliteMap_clicked()
{
    QString cmd = "showSatelliteMap()";
    ui->webEngine->page()->runJavaScript(cmd);      // 直接page()下就能够运行
}

在JS单向通讯中十分简单,也不须要使用QWebChannel信使,但该方法runJavaScript()没法在构造函数中使用,缘由不明。也能够这样使用:

connect(ui->webEngine,&QWebEngineView::loadFinished,[=](int){
             ui->webEngine->page()->runJavaScript(cmd1);

第二个参数SIGNAL位置的,只能使用这样的方式调用,若是使用SIGNAL(....loadFinished),报错。

4. 总结

经过这样的方法,咱们就完成了一个初级的过渡。本人因为是研究嵌入式的程序员,只是上位机学习简单的Qt作一点点当成辅助开发,并无什么高深的Qt技术,也正在学习中,欢迎讨论。

参考文献:

[1] 在水一方著.javascript调用Qt.CSDN博客.2011-07-18.

[2]Я!ńɡ著.QT5利用chromium内核与HTML页面交互.CNBLOGS. 2015-11-17.

[3]liuyez123著.[实现QT与HTML页面通讯]. CSDN博客. 2016-01-13.


版权声明:

1. 本文为MULTIBEANS团队研发跟随文章,未经容许不得转载。

2· 文中涉及的内容如有侵权行为,请与本人联系,本人会及时删除。

3· 尊重成果,本文将用的参考文献所有给出,向无私的工程师,爱好者致敬。


** 博文Markdown原版下载:http://pan.baidu.com/s/1qXGljC4 提取码:uk3b **

相关文章
相关标签/搜索