由于需要集成浏览器功能并用C++实现图形功能,最早是想通过QWebEngineView+QWebChannel+js的方式,实现c++与js的通讯。
qt中有很多文档,但访问不成功。走过好多弯路,改用这套方法。
qt的跨平台性给编译造成很多麻烦。
测试过的环境:
x64可以在qt 5.12+vs2017+64bit上通过
x86可以在qt5.6.2+vs2013+32bit上通过
另实现了浏览器全屏窗体。
废话不多说
新建个MainWindow,HttpServer
httpserver.h
#ifndef HTTPSERVER_H
#define HTTPSERVER_H
#include <QCoreApplication>
#include <QNetworkInterface>
#include <iostream>
#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QDebug>
#define PORT 12000
class HttpServer: public QObject
{
Q_OBJECT
public:
explicit HttpServer(QObject *parent = 0);
~HttpServer();
QTcpSocket *socket;
int port();
public slots:
void myConnection();
void readMessage();
private:
QTcpServer *server;
int _port;
signals:
};
#endif // HTTPSERVER_H
httpserver.cpp
#include "httpserver.h"
#include <QFile>
#include <QChar>
#include <QMessageBox>
using namespace std;
HttpServer::HttpServer(QObject *parent) : QObject(parent)
{
socket = 0; // 客户端socket
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()),this, SLOT(myConnection()));
qDebug()<< "HttpServer start listen, port:"<< PORT;
if(server->listen(QHostAddress::Any, PORT)) {
qDebug()<<"success";
} else {
qDebug()<<"failed";
}
}
int HttpServer::port() {
return PORT;
}
void HttpServer::readMessage(){
QString readmsg = socket->readAll();
// 通过URL取文件路径,具体看下面说明
QStringList msgList = readmsg.split('\n');
QString strUrl = msgList.first().toLower();
strUrl.replace("get /", "");
strUrl.replace(" http/1.1", "");
strUrl.replace("\r", "").replace("\n", "");
strUrl.trimmed();
QMessageBox::information(NULL,QString().fromLocal8Bit("接收前端的数据"), strUrl);
//http协议返回串
//QString lens(QString::number( barr.length()));
QString lens(QString::number(strUrl.length()));
socket->write("HTTP/1.1 200 OK\r\n");
socket->write("Content-Type: text/html\r\n");
socket->write("Accept-Ranges: bytes\r\n");
QString sLen("Content-Length: "+lens+"\r\n\r\n");
socket->write(sLen.toLatin1());
socket->write(strUrl.toLatin1());
socket->flush();
connect(socket, SIGNAL(disconnected()),socket, SLOT(deleteLater()));
socket->disconnectFromHost();
}
void HttpServer::myConnection()
{
socket = server->nextPendingConnection();
if (socket) {
connect(socket, SIGNAL(disconnected()),socket, SLOT(deleteLater()));
connect(socket,SIGNAL(readyRead()),this,SLOT(readMessage())); //有可读的信息,触发读函数槽
}
}
HttpServer::~HttpServer()
{
if (socket)
socket->close();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWebEngineView>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
QWebEngineView* view;
private:
Ui::MainWindow *ui;
void resizeEvent(QResizeEvent *event);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "httpserver.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//浏览器支持
view = new QWebEngineView(this);
view->load(QUrl(QApplication::applicationDirPath()+"./home.html"));
view->showMaximized();
//启动Http服务
HttpServer *server=new HttpServer(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
view->resize(this->size());
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
home.html
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="./script/node_modules/_jquery@3.3.1@jquery/dist/jquery.min.js"></script>
</head>
<body>
<body>
<div id="divMsg">Hello World!</div>
<input id="btnShow" type="button" value="显示" />
<input id="btnHide" type="button" value="隐藏" /><br />
<input id="btnChange" type="button" value="修改内容为 Hello World, too!" />
<br/>
<input id="btnSend" type="button" value="打开QT窗口"/><br/>
<script type="text/javascript">
$("#btnShow").bind("click", function (event) { $("#divMsg").show(); });
$("#btnHide").bind("click", function (event) { $("#divMsg").hide(); });
$("#btnChange").bind("click", function (event) { $("#divMsg").html("Hello World, too!"); });
$("#btnSend").bind("click", function (event) {
$.ajax({
type: "get", //提交方式
url: "http://127.0.0.1:12000/12345678",//写死即可路径,12345678是参数
});
});
</script>
</body>
</body>
</html>
Doc.pro
#-------------------------------------------------
#
# Project created by QtCreator 2019-01-31T19:53:39
#
#-------------------------------------------------
QT += core gui webengine webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets network
TARGET = Doc
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += main.cpp mainwindow.cpp httpserver.cpp
HEADERS += mainwindow.h httpserver.h
FORMS += mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
提供源码及bin文件下载地址:https://download.csdn.net/download/mycn027/10947181