初识QtWebEngine

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>  

资源文件:
在这里插入图片描述
展示结果:
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值