QtWebEngine简介:
Qt WebEngine模块提供了一个web浏览器, 在不使用本地浏览器的情况下, 它可以很容易地把Web内容嵌入到Qt应用程序中.
Qt WebEngine为渲染HTML, XHTML和SVG文档,使用CSS和JavaScript, 提供了C++类和QML类型
页面的展示
首先我们需要在.pro文件中加入:QT += core gui webenginewidgets
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWebEngineView>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QWebEngineView *mpJSWebView;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mpJSWebView = new QWebEngineView();
//加载html界面(可以填绝对路径)
mpJSWebView->page()->load(QUrl("qrc:/html/static/main.html"));
mpJSWebView->show();
}
MainWindow::~MainWindow()
{
delete ui;
delete mpJSWebView;
}
附:本次示例将html文件作为资源文件加入到了项目中:
Qt与HTML页面间的通信:
QWebChannel将C++接口暴露给HTML,在HTML中调用qwebchannel.js。前提是建立tranport,QT只提供了QWebChannelAbstractTransport,需要自己实现,官方建议用QWebSocket实现,并个给出实例;
1、实现Transport类,内置一个WebSocket套接字;
2、实现新的Channel类,内置一个WebSocketServer;
3、利用新的Channel注册c++对象,从而HTML可以使用该对象;
4、通过以下三种方式进行C++与HTML的交互:
在HTML中连接c++ signal与js函数
在HTML中调用c++ public slots函数;
在HTML中调用c++ Q_INVOKABLE修饰的函数
通信两大必备要点:
1.必须在HTML中调用qwebchannel.js,该js文件时通信关键。
2.必须在Qt和HTML中注册通信管道。
创建一个新的Qt项目:
1.配置.pro文件:QT += core gui webenginewidgets
2.具体示例文件:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWebEngineView>
#include <QWebChannel>
#include "tinteractobj.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void OnReceiveMessageFromJS(QString strParameter);
private slots:
void on_Button_send_clicked();
signals:
void SigSendMessageToJS(QString strParameter);
private:
Ui::MainWindow *ui;
QWebEngineView *mpJSWebView;
};
#endif // MAINWINDOW_H
函数说明:
OnReceiveMessageFromJS:用于处理自定义信息接受类TInteractObj从Web端接收到的数据
信号说明:
SigSendMessageToJS:该信号与自定义信息接受类TInteractObj相连接用于触发发送数据信号
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mpJSWebView = new QWebEngineView();
QWebChannel *pWebChannel = new QWebChannel(mpJSWebView->page());
//自定义通道类
TInteractObj *pInteractObj = new TInteractObj(this);
//注册通道时"interactObj"名字应该与html的变量名一致
pWebChannel->registerObject(QStringLiteral("interactObj"), pInteractObj);
mpJSWebView->page()->setWebChannel(pWebChannel);
mpJSWebView->page()->load(QUrl("qrc:/html/static/main.html"));
mpJSWebView->show();
connect(pInteractObj, &TInteractObj::SigReceivedMessFromJS,
this, &MainWindow::OnReceiveMessageFromJS);
connect(this,&MainWindow::SigSendMessageToJS,
pInteractObj, &TInteractObj::SigSendMessageToJS);
}
MainWindow::~MainWindow()
{
delete ui;
delete mpJSWebView;
}
void MainWindow::on_Button_send_clicked()
{
QString strMessage = ui->lineEdit->text().trimmed();
if (strMessage.isEmpty())
{
return;
}
emit SigSendMessageToJS(strMessage);
}
void MainWindow::OnReceiveMessageFromJS(QString strParameter)
{
if (strParameter.isEmpty())
{
return;
}
ui->board_message->setText(strParameter);
}
tinteractobj.h
#ifndef TINTERACTOBJ_H
#define TINTERACTOBJ_H
#include <QObject>
class TInteractObj : public QObject
{
Q_OBJECT
public:
TInteractObj(QObject *parent);
~TInteractObj();
//关键字 Q_INVOKABLE 用于识别槽,该函数名必须与Web中js的发送函数同名
Q_INVOKABLE void JSSendMessage(QString strParameter);
signals:
void SigReceivedMessFromJS(QString strParameter);
//该信号名必须与js中接收函数同名
void SigSendMessageToJS(QString strParameter);
};
#endif // TINTERACTOBJ_H
函数说明:
JSSendMessage :该函数可以看作是Web端向Qt传输数据的槽函数,必须与js中发送函数同名
信号说明:
SigReceivedMessFromJS :当web端有数据传送到Qt时调用JSSendMessage时触发
SigSendMessageToJS:当Qt有数据传到Web时触发,必须与js中接收函数同名
tinteractobj.cpp
#include "tinteractobj.h"
TInteractObj::TInteractObj(QObject *parent)
:QObject(parent)
{
}
TInteractObj::~TInteractObj()
{
}
void TInteractObj::JSSendMessage(QString strParameter)
{
emit SigReceivedMessFromJS(strParameter);
}
测试HTML文件:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="qrc:/html/qwebchannel.js"></script>
<script type="text/javascript">
//---Web展示接收到的信息---
function output(message)
{
var output = document.getElementById("output");
output.innerHTML = output.innerHTML + message + "\n";
}
//Web initial loading
window.onload = function() {
output("");
new QWebChannel(qt.webChannelTransport, function(channel) {
//获取Qt发的数据
var interactObj = channel.objects.interactObj;
//Web send message to Qt
document.getElementById("send").onclick = function() {
var input = document.getElementById("input");
if (!input.value) {
return;
}
//Web向Qt发送数据
interactObj.JSSendMessage(input.value);
input.value = "";
}
//Web接收到来着Qt的数据传输信号的槽
interactObj.SigSendMessageToJS.connect(function(str) {
output("Received string from Qt: " + str);
});
});
}
</script>
<style type="text/css">
html {
height: 100%;
width: 100%;
}
#input {
width: 650px;
margin: 0 10px 0 0;
}
#send {
width: 90px;
margin: 0;
}
#output {
width: 770px;
height: 550px;
}
</style>
</head>
<body>
<textarea id="output" readonly="readonly"></textarea><br />
<input id="input" />
<input type="submit" id="send" value="Send" onclick="javascript:click();" />
</body>
</html>
资源文件:
展示结果: