这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
使用qt官方提供的QWebChannel,qwebchannel.js脚本,通过这个中间人的注入网页的qt对象,这样网页也能调用qt的函数
1. HTML网页发消息给qt的Chrome内核
class JsContext : public QObject{
Q_OBJECT
public:
explicit JsContext(QObject * parent = nullptr);
signals:
void recvdMsg(const QString& msg);
public:
// 向页面发送消息
void sendMsg(QWebEnginePage * page, const QString& msg);
public slots:
// 接收到页面发送来的消息
void onMsg(const QString& msg);
};
2. 初始化生成webChannel实例和jsContext(网页的qt对象)
m_jsContext = new JsContext(this);
m_webChannel = new QWebChannel(this);
m_webChannel->registerObject("context", m_jsContext); // 这里的"context"是HTML网页定义好的qt对象
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);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webchannel测试</title>
</head>
<body>
<input id="待发送消息" type="text" name="msgText" />
<input type="button" value="发送消息到浏览器" onclick="onBtnSendMsg()" />
</body>
</html>
// 接收qt发送的消息
function recvMessage(msg){
alert("接收到qt发送的消息:" + msg);
}
// 首先Qt端,上面的JsContext类已经声明了发送消息的方法sendMsg,其具体实现如下:
void JsContext::sendMsg(QWebEnginePage* page, const QString& msg){
page->runJavaScript(QString("recvMessage('%1');").arg(msg));
}
3. qwebchannel.js脚本里导入方式是node的方式,得改成ES6导入方式
// required for use with nodejs
// if(typeof module ===' object){
// module.exports = {
// Qwebchannel: Qvebchannet
// };
// }
export{
QNebChannel
}
4. 对QWebChannel.js封装,其中channel.objects.context的“context”是qt代码预先注册起名的变量,onMsg,recvMessage也要预先在qt代码里注册的函数,而window.qt是qt浏览器的注入对象,接下来就可以通过约定注册函数进行交互通信
import QWebChannel from "qwebchannel.js"l;
class Qweb {
constructor() {
this.qtContext = undefined;
this.init()
}
// 初始化
init() {
if (typeof window.qt !== 'undefined') {
new QWebChannel(window.qt.webChannelTransport, function (channel) {
this.qtContext = channel.objects.context;
}
);
}
else {
console.log("window.qt对象获取失败!");
}
}
// 向qt发送消息
sendMessage(msg) {
if (typeof qtContext == 'undefined') {
console.log("qtContext对象获取失败!");
}
else {
this.qtContext.onMsg(msg);
}
}
// 控件控制函数
onBtnSendMsg() {
let cmd = document.getElementById("待发送消息").value;
sendMessage(cmd);
}
// 接收qt发送的消息
recvMessage(msg) {
console.log("接收到Qt发送的消息:" + msg);
}
}
export default new Qweb()