QWebEngineView和QWebChanel的使用。

85 篇文章 1 订阅

想要在qt中加载网页到widget中,需要使用到QWebEngineView,想要和网页端通信可以使用到QWebChanel。当然还可以使用QWebSocket。
QWebEngineView使用方法如下:

    m_pWebView = new QWebEngineView(this);
    QString htmlPath = QApplication::applicationDirPath()+"/test.html";
    QFile file(htmlPath);
    if (!file.exists())
        return;
    m_pWebView->load(QUrl("file:///" + htmlPath));

使用QWebChanel方法如下:

m_pWebChannel = new QWebChannel(this);
m_pWebChannel->registerObject(QString("qtui"), this);//qtui这个标识是可以随意定义,只要web端中html也是使用qtui就能通讯上了。
m_pWebView->page()->setWebChannel(m_pWebChannel);

QWebChanel和web的通讯方法如下:
1、发信号,web负责连接。
2、创建槽函数,让web自己调用这个槽。
3、调用runJavaScript()这个接口,直接调用web定义的函数即可,且它支持同步异步发送。
4、头文件创建对象属性,让web端直接使用这个对象,我们就能从这个对象中拿到web赋予的值。如下:m_content。
在这里插入图片描述
在这里插入图片描述
代码示例1如下:
头文件

#ifndef WEBTEST_H
#define WEBTEST_H
#include <QtWidgets>
#include <QWebEngineView>
#include <QWebChannel>

class WebTest : public QWidget
{
    Q_OBJECT
public:
    WebTest(QWidget *parent = nullptr);

private:
    void initUi();
    void initConncetion();
    // 加载html文件
    void loadHtml();
    // 获取js函数返回值
    QString getJsRetString();

public slots:
    void recieveJsMessage(const QString& jsMsg);

private:
    QWebEngineView *m_pWebView;
    QWebChannel* m_pWebChannel;
    QPushButton* m_callJSBtn;
    QPushButton* m_getJsRetBtn;
    QLabel* m_lab;
};

#endif // WEBTEST_H

cpp文件

#include "webtest.h"
#include <QFile>
#include <QCoreApplication>

WebTest::WebTest(QWidget *parent) : QWidget(parent)
{
    initUi();
    initConncetion();
}

void WebTest::initUi()
{
    m_callJSBtn = new QPushButton(QStringLiteral("调用JS"),this);
    m_getJsRetBtn = new QPushButton(QStringLiteral("获取JS返回值"),this);
    m_lab = new QLabel(this);
    m_pWebView = new QWebEngineView(this);
    m_pWebChannel = new QWebChannel(this);

    QGridLayout* lay = new QGridLayout();
    lay->addWidget(m_pWebView,0,0,5,5);
    lay->addWidget(m_callJSBtn,0,5,1,1);
    lay->addWidget(m_getJsRetBtn,1,5,1,1);
    lay->addWidget(m_lab,2,5,1,1);
    this->setLayout(lay);

    m_callJSBtn->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
    m_getJsRetBtn->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
    m_lab->setStyleSheet("background:rgba(0,0,155,100)");

    loadHtml();

    m_pWebChannel->registerObject(QString("qtui"), this);
    m_pWebView->page()->setWebChannel(m_pWebChannel);
}

void WebTest::initConncetion()
{
    // 调用JS
    connect(m_callJSBtn, &QPushButton::clicked, [&]()
    {
        QString jsStr = QString("addCircle()");
        m_pWebView->page()->runJavaScript(jsStr);//异步调用
    });

    // 获取JS返回值
    connect(m_getJsRetBtn, &QPushButton::clicked, [&]()
    {
        auto str = getJsRetString();
        m_lab->setText(str);
    });
}

//加载地图
void WebTest::loadHtml()
{
    QString htmlPath = QCoreApplication::applicationDirPath() + "/BMap.html";

    QFile file(htmlPath);
    if (!file.exists())
    {
        return;
    }

    m_pWebView->load(QUrl("file:///" + htmlPath));
}

//获取web端返回值
QString WebTest::getJsRetString()
{
    QEventLoop loop;
    QString jsStr = "getInfo();";

    QString retStr{};
    // 同步通过loop循环等到回调上来数据再继续
    m_pWebView->page()->runJavaScript(jsStr, [&](const QVariant &v)
    {
        retStr = v.toString();
        loop.quit();
    });
    loop.exec();
    return retStr;
}

//接收来自webhtml的消息
void WebTest::recieveJsMessage(const QString& jsMsg)
{
    m_lab->setText(jsMsg);
}

html文件

<!DOCTYPE html>
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <style type="text/css">
        body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
        </style>
        <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=AEdSNAu4uSOTMaQgiuFizrkNwheoSVHF"></script>
        <script src="./qwebchannel.js"></script>
        <title>Web测试</title>
</head>
<body>
        <div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
// 百度地图API功能
var map = new BMap.Map("allmap");    // 创建Map实例
map.centerAndZoom(new BMap.Point(116.404, 39.915), 11);  // 初始化地图,设置中心点坐标和地图缩放级别
//添加地图类型控件
map.addControl(new BMap.MapTypeControl({
        mapTypes:[
    BMAP_NORMAL_MAP,
    BMAP_HYBRID_MAP
]}));
map.setCurrentCity("北京");          // 设置地图显示的城市 此项是必须设置的
map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放


// 添加一个圆形覆盖物
function addCircle()
{
    var point = new BMap.Point(116.404, 39.915);
    var circle = new BMap.Circle(point, 6000, { strokeColor: "red", strokeWeight: 5, strokeOpacity: 0.3 }); //创建圆
    map.addOverlay(circle);            //增加圆

// 给这个circle添加一个点击事件
    circle.addEventListener("click", function (event)
    {
        new QWebChannel(qt.webChannelTransport, function (channel) {
            var qtui = channel.objects.qtui;
            qtui.recieveJsMessage("你点我干啥!");
        })
    });
}

// 获取字符串文本
function getInfo()
{
    var textString = "HTML js返回值";
    return textString;
}
</script>

代码示例2如下:
头文件

#ifndef TESTINTERFACE_H
#define TESTINTERFACE_H

#include <QObject>
#include <QMessageBox>

class testinterface : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString content MEMBER m_content)
public:
    testinterface();
    void send(int type,QString msg);
signals:
    void dataChanged(QString content);
    void sendData(QString content);
public slots:
    void jscallme(QString msg);
private:
    QString m_content;
};

#endif // TESTINTERFACE_H

cpp文件

#include "testinterface.h"

testinterface::testinterface()
{
}

void testinterface::send(int type, QString msg)
{
    if (type == 0)
    {
        emit dataChanged(msg);
    }
    else if (type == 1)
    {
        emit sendData((msg));
    }
}

void testinterface::jscallme(QString msg)
{
    QMessageBox::information(NULL, "title", QString(QStringLiteral("测试传参:%1\n测试变量:%2")).arg(msg).arg(m_content));
}

html文件

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title></title>
</head>
<body>
  <script src="qwebchannel.js"></script> 
  <script type="text/javascript">

  var recvData=function(text)
  {
    document.write("测试2:"+text+"</br>");
  }
  var updateattribute=function(text)
  {	
    document.write("测试1:"+text+"</br>");
  }

  new QWebChannel(qt.webChannelTransport,
  function(channel){
  var testinterface = channel.objects.testinterface;
  window.foo = testinterface;
  testinterface.content="恭喜发财";
  testinterface.jscallme("新年快乐");
  testinterface.dataChanged.connect(updateattribute);
  testinterface.sendData.connect(recvData);

  });
  </script>
</body>
</html>

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值