前言:此项目使用达梦数据库,以Qt制作服务器,Html制作网页客户端界面,可以通过任意浏览器访问。
1、Qt与网页进行数据交互
1.1、第一步:准备qwebchannel.js文件
直接在qt的安装路径里复制即可
1.2、第二步:在Qt的.pro文件加载webchannel组件
在.pro文件添加如下组件:
QT += core gui sql webchannel widgets websockets
1.3、第三步:在main.cpp文件注册通信类
#include "MainWindow.h"
#include <QApplication>
#include <QDesktopServices>
#include <QDialog>
#include <QDir>
#include <QFileInfo>
#include <QUrl>
#include <QWebChannel>
#include <QWebSocketServer>
#include "core.h"
#include "../shared/websocketclientwrapper.h"
#include "../shared/websockettransport.h"
#include <QObject>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//以下三行代码可有可无,用来确保qwebchannel.js文件放在自己指定的文件夹里
QFileInfo jsFileInfo(QDir::currentPath() + "/Web/js/qwebchannel.js");
if (!jsFileInfo.exists())
QFile::copy(":/qtwebchannel/qwebchannel.js",jsFileInfo.absoluteFilePath());
// 设置QWebSocketServer
QWebSocketServer server(QStringLiteral("QWebChannel Standalone Example Server"), QWebSocketServer::NonSecureMode);
if (!server.listen(QHostAddress::Any, 12345))//12345是端口号,可以自己指定
{
qFatal("Failed to open web socket server.");
return 1;
}
// 在QWebChannelAbstractTransport对象中包装WebSocket客户端
WebSocketClientWrapper clientWrapper(&server);
// setup the channel
QWebChannel channel;
QObject::connect(&clientWrapper, &WebSocketClientWrapper::clientConnected,
&channel, &QWebChannel::connectTo);
MainWindow w;//MainWindow 类是我自己搭建的服务器界面类
Core core(&w);//Core 类是我自己搭建的用来作为Qt与Html通信的类
channel.registerObject(QStringLiteral("core"), &core);//把Core注册成通信类
w.show();//显示服务器界面
return a.exec();
}
1.4、第四步:创建Core通信类
Core.h
#ifndef CORE_H
#define CORE_H
#include "MainWindow.h"
#include <QObject>
/*
An instance of this class gets published over the WebChannel and is then accessible to HTML clients.
该类的一个实例通过WebChannel发布,然后HTML客户端可以访问它。
*/
class Core : public QObject
{
Q_OBJECT
public:
Core(MainWindow *dialog, QObject *parent = nullptr)
: QObject(parent), m_dialog(dialog)
{
connect(dialog, &MainWindow::sendText, this, &Core::sendText);
}
signals:
/*
This signal is emitted from the C++ side and the text displayed on the HTML client side.
该信号从Qt端发出,并在HTML客户端显示文本。
*/
void sendText(const QString &text);//html那边会监听这个信号,Qt这边发送text,html会直接接收到
public slots:
/*
This slot is invoked from the HTML client side and the text displayed on the server side.
此槽从HTML客户端调用,并在服务器端显示文本。
*/
void receiveText(const QString &text)//Html那边可以直接调用这个函数
{
qDebug()<<text;//text就是Html发过来的数据
//m_dialog->displayMessage(MainWindow::tr("客户端: %1").arg(text));
}
private:
MainWindow *m_dialog;
};
#endif // CORE_H
1.5、第五步:创建html客户端
chatRoom.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="../js/qwebchannel.js"></script>
<script type="text/javascript">
//BEGIN SETUP
function output(message) {
var output = document.getElementById("output");
output.innerHTML = output.innerHTML + message + "\n";
}
window.onload = function() {
if (location.search != "")
var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]);
else
var baseUrl = "ws://localhost:12345";
output("系统:连接WebSocket服务器" + baseUrl + ".");
var socket = new WebSocket(baseUrl);
socket.onclose = function() {
console.error("web channel closed");
};
socket.onerror = function(error) {
console.error("web channel error: " + error);
};
socket.onopen = function() {
output("系统:连接WebSocket,设置QWebChannel.");
new QWebChannel(socket, function(channel) {
output("系统:连接成功!");
// make core object accessible globally
window.core = channel.objects.core;
document.getElementById("send").onclick = function() {
var input = document.getElementById("input");
var text = input.value;
if (!text) {
return;
}
output("客户端:" + text);
input.value = "";
core.receiveText(text);
}
core.sendText.connect(function(message) {
output("服务器: " + message);
});
core.receiveText("客户端已连接,准备发送/接收消息!");
output("客户端:客户端已连接,准备发送/接收消息!");
});
}
}
//END SETUP
</script>
<style type="text/css">
html {
height: 100%;
width: 100%;
}
#input {
width: 400px;
margin: 0 10px 0 0;
}
#send {
width: 90px;
margin: 0;
}
#output {
width: 500px;
height: 300px;
}
</style>
</head>
<body>
<textarea id="output"></textarea><br />
<input id="input" /><input type="submit" id="send" value="Send" οnclick="javascript:click();" />
</body>
</html>
2、问题
2.1、问题一:Cannot invoke unknown method of index -1 on object webTransport(0x…)
问题描述:运行时,Qt向Js端发送消息没有问题,Js端向Qt端发送消息时失败。
原因及解决办法:使用Qt 5.11.2编译生成的可执行程序,而网页端用的是Qt 5.14的qwebchannel.js文件,版本不兼容导致的,换成对应的qwebchannel.js文件就好了
2.2、问题二:Qwebchannel is not defined at webSocket.socket.onopen
问题描述:加载时无法连接qt。
原因及解决办法:没有加载qwebchannel.js文件
<script type="text/javascript" src="../js/qwebchannel.js"></script>