1、通过使用QtWebEngine加载相关页面,然后用QtWebChannel作为Qt与Javascript交互通讯的通道
1)pro中添加对应模块
QT += webenginewidgets webchannel
2)demo组成:QT界面+html5+qwebchannel.js(Qt官方自带)
2、相关伪代码
1)Qt窗口业务实现
void MainWindow::setupUI()
{
if (m_pContentTextEdit == Q_NULLPTR)
{
m_pContentTextEdit = new QPlainTextEdit(this);
m_pContentTextEdit->setMidLineWidth(400);
m_pContentTextEdit->setReadOnly(true);
}
if (m_pSendLineEdit == Q_NULLPTR)
{
m_pSendLineEdit = new QLineEdit(this);
}
QPushButton *pSendBtnByJavaScript = new QPushButton("SendToJS", this);
QHBoxLayout *pQtSendHLayout = new QHBoxLayout;
pQtSendHLayout->setMargin(0);
pQtSendHLayout->setSpacing(0);
pQtSendHLayout->addWidget(m_pSendLineEdit);
pQtSendHLayout->addSpacing(5);
pQtSendHLayout->addWidget(pSendBtnByJavaScript);
QVBoxLayout *pTotalVLayout = new QVBoxLayout;
pTotalVLayout->setMargin(5);
pTotalVLayout->setSpacing(0);
pTotalVLayout->addWidget(m_pContentTextEdit);
pTotalVLayout->addSpacing(5);
pTotalVLayout->addLayout(pQtSendHLayout);
if (m_pJSWebView == Q_NULLPTR)
{
m_pJSWebView = new QWebEngineView(this);
m_pJSWebView->setFixedSize(600,650);
InjectJsFile(QApplication::applicationDirPath() + "/qwebchannel.js");
InjectJsFile(QApplication::applicationDirPath() + "/bridge.js");//web js接口
m_pJSWebView->page()->load(QUrl::fromLocalFile(QApplication::applicationDirPath() + "/JSTest.html"));
m_pJSWebView->show();
}
QWebChannel *pWebChannel = new QWebChannel(m_pJSWebView->page());
JSBridge *pJSBridge = new JSBridge(this);
pWebChannel->registerObject(QStringLiteral("jsBridgeObj"), pJSBridge);//注册Qt对象
m_pJSWebView->page()->setWebChannel(pWebChannel);
QVBoxLayout *pJSTotalVLayout = new QVBoxLayout();
pJSTotalVLayout->setMargin(0);
pJSTotalVLayout->setSpacing(0);
pJSTotalVLayout->addWidget(m_pJSWebView);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setMargin(5);
mainLayout->setSpacing(0);
mainLayout->addLayout(pTotalVLayout);
mainLayout->addSpacing(5);
mainLayout->addLayout(pJSTotalVLayout);
setLayout(mainLayout);
this->setFixedSize(1000, 700);
connect(pSendBtnByJavaScript, &QPushButton::clicked, this, &MainWindow::OnSendMessageByJavaScript);
connect(pJSBridge, &JSBridge::sigRecvMsgFromJS,this,[&](QString strMsg){
m_pContentTextEdit->appendPlainText(strMsg);
});
connect(this, &MainWindow::sigSendMessageToJS,
pJSBridge, &JSBridge::sigSendMessageToJS);
}
void MainWindow::OnSendMessageByJavaScript()
{
QString strMessage = m_pSendLineEdit->text().trimmed();
if (strMessage.isEmpty())
{
return;
}
//直接运行js
m_pJSWebView->page()->runJavaScript(QString("jsBridgeAnswerHtml.output('%1');").arg(QString("Received Msg from Qt: %1").arg(strMessage)));
//通过信号方式发消息
emit sigSendMessageToJS(QString("Received Msg from Qt Sig: %1").arg(strMessage));
m_pSendLineEdit->clear();
}
bool MainWindow::InjectJsFile(const QString &strFileName) {
QFile file(strFileName);
if (file.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&file);
QWebEngineScript script;
script.setSourceCode(in.readAll());
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
script.setRunsOnSubFrames(true);
script.setWorldId(QWebEngineScript::MainWorld);
m_pJSWebView->page()->scripts().insert(script);
file.close();
return true;
}
return false;
}
2)Qt和h5交互注册类
#ifndef JSBRIDGEBASE_H
#define JSBRIDGEBASE_H
#include <QObject>
class JSBridge : public QObject
{
Q_OBJECT
public:
explicit JSBridge(QObject *parent = nullptr);
virtual ~JSBridge();
//web 页面调用Qt公共函数
Q_INVOKABLE void sendMsg(QString strMsg);
signals:
void sigRecvMsgFromJS(QString strMsg);
void sigSendMessageToJS(QString strMsg);
public slots:
void request(QString strMsg);
};
#endif // JSBRIDGEBASE_H
void JSBridge::sendMsg(QString strMsg)
{
emit sigRecvMsgFromJS("Received Msg from JS.sendMsg: "+strMsg);
}
void JSBridge::request(QString strMsg) {
emit sigRecvMsgFromJS("Received Msg from JS.slot: "+strMsg);
}
3)html代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="./test.js"></script>
<script type="text/javascript">
//---Web show receive message---
function Test() {
var input = document.getElementById("input");
if (!input.value) {
return;
}
//Web use the interface of Qt
jsBridgeAnswerCef.sendMsgToQt(input.value);
input.value = "";
}
</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="SendToQt" onclick="Test()" />
</body>
</html>
4)bridge.js和test.js
bridge.js:
var jsBridgeAnswerCef = {};
window.onload = function(){
new QWebChannel(qt.webChannelTransport, function(channel)
{
var obj = channel.objects.jsBridgeObj;
jsBridgeAnswerCef.sendMsgToQt = function (data)
{
obj.request(data);
obj.sendMsg(data);
}
obj.sigSendMessageToJS.connect(function(str) {
jsBridgeAnswerHtml.output(str);
});
});
}
test.js:
var jsBridgeAnswerHtml = {};
jsBridgeAnswerHtml.output = function (message)
{
var output = document.getElementById("output");
output.innerHTML = output.innerHTML + message + "\n";
}
3、运行效果
4、代码链接
https://download.csdn.net/download/qqzhaojianbiao/19058964