Qt实现网页与本地应用(QWebEngine应用)之间的通讯(QWebChannel的使用) - Go语言中文社区

Qt实现网页与本地应用(QWebEngine应用)之间的通讯(QWebChannel的使用)


导读:

       这篇文章会通过简单的步骤及最简单的例子来介绍如何使用QWebChannel实现网页端跟本地应用之间的通讯,也就是两者之间的相互操作,这里不会介绍基础理论及这种通讯是怎么实现的,这篇文章的核心以最快的速度告诉你,如何把这个通讯过程搭建起来。这里说的本地应用就是使用QWebEngine实现的浏览器。

前提:

       这篇文章是假设你已经有使用QWebEngine实现一个能打开网页的简单浏览器的基础的,因为不介绍这部分内容,但是例子里也有,也很简单,看代码里的注释也应该能快速搭建起来。

流程介绍: 

       一、实现一个继承于QObject的类(以下简称通信类)此类包含本地应用与网页端通信的所有方法

       二、给本地应用的网页载体QWebEnginePage对象注册通信类对象

       三、网页实现中引入qwebchannel.js,创建网页端的QWebChannel对象并与本地应用的通信类对像进行关联,最终实现网页端能够直接访问通信类的方法与本地应用进行通讯

详细介绍:

       一、自实现一个继承于QObject的类,注意,要继承于QObject,因为需要用到信号槽,这个类的主要作用是实现本地应用与网页端通信的方法,这个就时上面步骤介绍中所说的通讯类,无论本地应用还是网页端都是直接调用这个通讯类的方法来实现两者之间的通讯的。例如下面例子中的QWebChannelClass类。重点:本地应用与网页端之间的通讯过程,是通过信号和槽函数实现的,本地应用通过发送信号达到把信息发送到网页端,而网页端通过直接调用槽函数实现把信息传到本地应用。很简单,就是本地应用通过发送通讯类的信号通知网页端,网页端通过直接调用通讯类的槽函数来通知本地应用。网页端对本地应用的操作一定要调用槽函数,写在public slots 限定符下面的槽函数,不能是普通的public函数。下面对号入座看通讯类的例子

qwebchannelclass.h:

#ifndef QWEBCHANNELCLASS_H
#define QWEBCHANNELCLASS_H
#include <QObject>
class QWebChannelClass : public QObject
{  
  Q_OBJECT
public:   
 explicit QWebChannelClass(QObject *parent = nullptr);
signals:   
 void fromLocalToWebPage(const QString& strTemp);     //信号,发送这个信号就会把信息发送到网页端
public slots:  
  void fromWebPageToLocal(const QString& strTemp);    //槽函数,网页端将通过这个函数把信息传回本地应用。
};
#endif // QWEBCHANNELCLASS_H

qwebchannelclass.cpp:

#include "qwebchannelclass.h"
#include <QDebug>
QWebChannelClass::QWebChannelClass(QObject *parent) : QObject(parent)
{

}
void QWebChannelClass::fromWebPageToLocal(const QString& strTemp)
{  
    qDebug()<<QString("string from WebPage:%1").arg(strTemp);    
    emit fromLocalToWebPage("fromLocalToWebPage");     //为了简单,当网页端调用槽函数时,直接在这里发送一个信号回网页端
}

二、注册通讯类,这个更简单,创建一个QWebChannel类对象,然后将步骤一中实现的通信类对象通过void QWebChannel::registerObject(const QString &id, QObject *object)注册到QWebChannel对象中,其中参数一是一个字符串,这个很重要,这个id将作为一个标识符参与网页端QWebChannel对象的创建,网页端通过这个id创建的对象将可以直接访问通信类的方法实现通信,注册好后将这个QWebChannel对象设置到即将加载我们指定网页的QWebEnginePage中(至于这个是什么原理实现的,暂时也没有研究,哪天弄明白了再更上来),下面看代码(完整代码看后面的Widget类:

QWebChannel *pChannel=new QWebChannel(this);    //创建一个Qwebchannel对象
pChannel->registerObject(QStringLiteral("channelObject"),m_pWebChannelClass); //注册通信类对像
m_pWebEngineView->page()->setWebChannel(pChannel);//将QWebChannel 对象设置到网页载体QWebEnginePage中

三、引入qwebchannel.js,创建网页端通信对象,qwebchannel.js在QtCreator安装目录下可以找到(直接在安装目录下检索就好了),下面代码中标黑的两行中第一行是固定的写法,第二行的可以理解为将本地通信类与网页端的对象关联起来使得网页端的对象可以像本地通信类对象那样使用通信类的信号和槽实现通信,详细看每句的注释

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<head>
  <script src="qwebchannel.js"></script>     <!--引入qwebchannel.js-->
</head>
<body >
  <script>
  var bridge;
       window.οnlοad=function init()
       {
                 new QWebChannel(qt.webChannelTransport,function (channel) {

 <!-- channelObject 是步骤二中注册qwebchannle对象中的标识符-->
                 bridge = channel.objects.channelObject;            

     <!--fromLocalToWebPage是cpp端声明的信号 response是信号带过来的参数 ,跟qt信号一样理解-->

                   bridge.fromLocalToWebPage.connect(function (response) {    
                     alert("received message from local:"+response);
                   });

                 });
       }
function fromWebToCpp(){          

<!-- fromWebPageToLocal是cpp端实现的槽函数 ,这里的123456将作为参数传递到本地应用中-->
                bridge.fromWebPageToLocal("123456");
            }
  </script>
  <body>
  <input id="add" type="button" value="msFromWebToCpp" class="button" οnclick="fromWebToCpp();"/>
  </body>
</body>
</html>

四、效果图,运行后点击网页端的按钮1,网页端会给本地传送2的123456,然后触发信号3,接着网页端会收到4显示的字符串fromLocalToWebPage

 

 

五、源代码,可以点击下载已经通过编译的代码:QtWebChannelDemon(包含已经编译通过的项目及测试html文件),也可以直接复制参考下面完整代码

1.QtWevChannelDemon.pro:


QT += core gui
QT +=webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QtWebChannelDemon
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES +=
main.cpp
widget.cpp
qwebchannelclass.cpp
HEADERS +=
widget.h
qwebchannelclass.h

2.main.cpp:

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{    
QApplication a(argc, argv);   
 Widget w;   
 w.show();    
return a.exec();
}

3.widget.h:

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QWebEngineView>
#include <QHBoxLayout>
#include "qwebchannelclass.h"
class Widget : public QWidget
{  
  Q_OBJECT

public:   
 Widget(QWidget *parent = 0);   
 ~Widget();    
void initWebChannel();
private:    
 QWebEngineView* m_pWebEngineView;    
 QHBoxLayout*    m_pHBoxLayout;   
 QWebChannelClass* m_pWebChannelClass;
};
#endif // WIDGET_H

4.widget.cpp

 #include "widget.h"
#include <QUrl>
#include <QWebChannel>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
m_pHBoxLayout=new QHBoxLayout(this);
m_pWebChannelClass =new QWebChannelClass(this);
m_pHBoxLayout->setContentsMargins(0,0,0,0);
m_pWebEngineView=new QWebEngineView;      //创建一个vebview
m_pHBoxLayout->addWidget(m_pWebEngineView);
initWebChannel();
m_pWebEngineView->load(QUrl("file:///E:/sources/qt/QtWebChannelDemon/test.html"));  //在webview中加载网页
}
Widget::~Widget()
{
}
void Widget::initWebChannel()
{
QWebChannel *pChannel=new QWebChannel(this);
pChannel->registerObject(QStringLiteral("channelObject"),m_pWebChannelClass);
m_pWebEngineView->page()->setWebChannel(pChannel);
}

 

5.qwebchannelclass.h

#ifndef QWEBCHANNELCLASS_H
#define QWEBCHANNELCLASS_H
#include <QObject>
class QWebChannelClass : public QObject
{    

Q_OBJECT

public:    
explicit QWebChannelClass(QObject *parent = nullptr);
signals:    
void fromLocalToWebPage(const QString& strTemp);
public slots:    
void fromWebPageToLocal(const QString& strTemp);
};
#endif // QWEBCHANNELCLASS_H
6.qwebchannelclass.cpp
#include "qwebchannelclass.h"
#include <QDebug>
QWebChannelClass::QWebChannelClass(QObject *parent) : QObject(parent)
{
}
void QWebChannelClass::fromWebPageToLocal(const QString& strTemp)
{    
qDebug()<<QString("string from WebPage:%1").arg(strTemp);    
emit fromLocalToWebPage("fromLocalToWebPage");
}

 

 

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Y_Bingo/article/details/82954940
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 20:58:30
  • 阅读 ( 1426 )
  • 分类:Go Web框架

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢