一、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>
二、示例:加载高德地图
来源:https://blog.csdn.net/qq_33638017/article/details/98625714