用qt+QWebEngineView+tcp实现js与c++的通讯

由于需要集成浏览器功能并用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

 

 

展开阅读全文

没有更多推荐了,返回首页