qt--QWebEngine加载高德地图

扶醉桌前 提交于 2019-11-28 19:48:41

一、js与c++交互

首先在所创建项目的.pro配置中添加webenginewidgets模块
QT += webenginewidgets
然后在主窗口初始化时创建QWebEngineView对象
m_webView = new QWebEngineView(this);
QStackedLayout* layout = new QStackedLayout(ui->frame);
ui->frame->setLayout(layout);
layout->addWidget(m_webView);
页面的加载和刷新
m_webView->load(url);
m_webView->reload();
辅助类JsContext
//jscontext.h
#ifndef JSCONTEXT_H
#define JSCONTEXT_H

#include <QObject>
#include <QWebEnginePage>

class JsContext : public QObject
{

    Q_OBJECT
   public:
       explicit JsContext(QObject *parent = nullptr);

   signals:
       void recvdMsg(const QString& msg); //向mainwindow传递消息

   public:
       // 向页面发送消息
       void sendMsg(QWebEnginePage* page, const QString& msg);

   public slots:
       // 接收到页面发送来的消息
       void onMsg(const QString& msg);
};

#endif // JSCONTEXT_H

#include "jscontext.h"

JsContext::JsContext(QObject *parent) : QObject(parent)
{

}
void JsContext::onMsg(const QString &msg)
{
    emit recvdMsg(msg);
}
void JsContext::sendMsg(QWebEnginePage* page, const QString& msg)
{
    page->runJavaScript(QString("recvMessage('%1');").arg(msg));
}


qt端QWebChannel的使用步骤
创建QWebChannel对象;
向QWebChannel对象注册Qt对象,例子里的Qt对象就是上面实现的JsContext对象。注意:这里注册时所用的名字“context”,就是js获取qt对象时所使用的索引名。
将设置好的QWebChannel对象设置为当前页面的通道。即调用QWebEnginePage的setWebChannel方法。注意:如果没有正确注册webchannel,在js调用qt对象时会出现qt对象为undefined的情况。
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_webView = new QWebEngineView(parent);
    QStackedLayout* layout = new QStackedLayout(ui->frame);
    ui->frame->setLayout(layout);
    layout->addWidget(m_webView);
    //m_webView->load(QUrl("http://www.qt.io/"));

    connect(ui->btnGo, &QPushButton::clicked, this, [this]() {
        QString url = ui->addressEdit->text();
        if (!url.isEmpty())
        {
            m_webView->load(url);
        }
    });
    /*
    connect(ui->btnRefresh, &QPushButton::clicked, this, [this]() {
        m_webView->reload();
    });
    */

    m_jsContext = new JsContext(this);
    m_webChannel = new QWebChannel(this);
    m_webChannel->registerObject("context", m_jsContext);
    m_webView->page()->setWebChannel(m_webChannel);

    connect(m_jsContext, &JsContext::recvdMsg, this, [this](const QString& msg) {
        ui->statusBar->showMessage(QString("Received message:%1").arg(msg), 3000);
    });

    connect(ui->btnSend, &QPushButton::clicked, this, [this]() {
        QString msg = ui->msgEdit->text();
        if (!msg.isEmpty())
        {
            m_jsContext->sendMsg(m_webView->page(), msg);
        }
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

js端
var context;
// 初始化
function init()
{
    if (typeof qt != 'undefined')
    {
        new QWebChannel(qt.webChannelTransport, function(channel)
        {
        context = channel.objects.context;
        }
        );
    }
    else
    {
        alert("qt对象获取失败!");
    }
}
// 向qt发送消息
function sendMessage(msg)
{
    if(typeof context == 'undefined')
    {
        alert("context对象获取失败!");
    }
    else
    {
        context.onMsg(msg);
    }
}
// 控件控制函数
function onBtnSendMsg()
{
    var cmd = document.getElementById("待发送消息").value;
    sendMessage(cmd);   
}
init();
// 接收qt发送的消息
function recvMessage(msg)
{
    alert("接收到Qt发送的消息:" + msg);
}
这里有几点需要注意的地方:

初始化时创建了一个QWebChannel对象,里面的第一个参数qt.webChannelTransport,只有Qt端正确地向页面设置了webchannel才能取到,否则会是undefined。
QWebChannel对象里的channel.objects对应了上面Qt实现里向webchannel注册的对象表,channel.objects.context即为从表中取出名为"context"的对象。
context.onMsg即为对context对象所提供的onMsg方法的调用。如果该对象没有提供这个方法,或者这个方法没有被声明为一个slot,则Qt端会报找不到方法的错。
c++向js传递
void JsContext::sendMsg(QWebEnginePage* page, const QString& msg)
{
    page->runJavaScript(QString("recvMessage('%1');").arg(msg));
}
js向c++传递
// 向qt发送消息
function sendMessage(msg)
{
    if(typeof context == 'undefined')
    {
        alert("context对象获取失败!");
    }
    else
    {
        context.onMsg(msg);
    }
}
html端
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webchannel测试</title>
</head>
<body>
    <p>webchannel test</p>
    <script type="text/javascript" src="./qwebchannel.js"></script>
    <script type="text/javascript" src="./my.js"></script>
    <input id="待发送消息" type="text" name="msgText" />
    <input type="button" value="发送消息到浏览器" onclick="onBtnSendMsg()" />
</body>
</html>

二、示例:加载高德地图

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!