添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1. QWebChannel

QWebChannel类的作用是向远端HTML客户端暴露 QObject。

QWebChannel填补了C++应用程序和HTML/JavaScript 应用程序之间的空白。通过将QObject派生对象发布到QWebChannel并在HTML中引入qwebchannel.js脚本可从此处获取。在HTML端,可以透明地访问QObject的属性、公共槽和方法。不需要手动消息传递和数据序列化,C++方面的属性更新和信号发射将自动传输到可能远程运行的HTML客户机。在客户端,将为任何发布的C++ QObject创建JavaScript对象。它反映了C++对象的API,因此可以直观地使用。
在这里插入图片描述
但是,Web端与C++之间怎么进行通信能? 有两个方法:

  • QWebEngine 提供一个 web 引擎,用于在 Qt 应用中嵌入任意的网页内容。Qt WebEngine 是基于 Chromium 项目实现的,提供了一个 js 的宿主环境,内部实现了js调用C++的环境;
  • Websocket C++端建立websocket server,Web端连接,qwebchannel.js会获取到C++端所有的属性、槽函数等。

2. 使用QWebEngine的示例

2.1 C++端代码

2.1.1 mainwindow.cpp

// 要导出的类,此类供js调用
m_myTestClass = new MyTestClass(this);
// 创建QWebChannel,把创建的类注册到QWebChannel中,js才能调用此类的方法
m_webChannel = new QWebChannel(this);
m_webChannel->registerObject("mytestclass", m_myTestClass);
// js与C++通信方式一、使用QWebEngineView加载网页,web端js与C++之间的通信
QString strHtml = QApplication::applicationDirPath() + "/../../testWeb/test.html";
// QWebEngineView 基于 Chromium 的 web 引擎
m_webEngineView = new QWebEngineView(this);
m_webEngineView->load(QUrl::fromLocalFile(strHtml));
m_webEngineView->page()->setWebChannel(m_webChannel);
ui->verticalLayout->addWidget(m_webEngineView);

导出类 MyTestClass,供js调用

2.1.2 mytestclass.h

#ifndef MYTESTCLASS_H
#define MYTESTCLASS_H
#include <QObject>
#include <QThread>
class MyTestClass : public QObject
    Q_OBJECT
    // 导出的属性
    Q_PROPERTY(QString navStatus MEMBER m_navStatus NOTIFY navStatusChanged)
public:
    explicit MyTestClass(QObject *parent = nullptr);
signals:
    // 导出的事件
    void navStatusChanged(const QString& navStatus);
public slots:
    // 导出的槽函数
    void function1(const QString& str);
private:
    void setNavStatus(const QString& status);
    QString m_navStatus;
#endif // MYTESTCLASS_H

2.1.3 mytestclass.cpp

#include "mytestclass.h"
#include <QMessageBox>
#include <QVariant>
#include <QDebug>
MyTestClass::MyTestClass(QObject *parent) : QObject(parent),
    m_navStatus("hello")
void MyTestClass::function1(const QString& str)
    setNavStatus(str);
    qDebug() << __FUNCTION__ << str;
void MyTestClass::setNavStatus(const QString &status)
    m_navStatus = status;
    emit navStatusChanged(m_navStatus);

2.2 Web端

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
    <button id="callcpp" onclick="callcpp()">callcpp</button>
    <button onclick="getValue()">getValue</button>
    <script src="qwebchannel.js"></script>
    <script type="text/javascript">
        var webObj;
        // 创建Webchannel,与C++端建立连接
        new QWebChannel(qt.webChannelTransport, function (channel) {
                // 获取类的对象
                webObj = channel.objects.




    
mytestclass;
                // 类的事件
                webObj.navStatusChanged.connect(function(arg){
                    alert("navStatusChanged: " + arg);
                });
            });
        function callcpp(){
            // 类的方法
            webObj.function1('this is a test');
        function getValue(){
            // 类的属性值
            var status = webObj.navStatus;
            alert(status);
    </script>
</body>
</html>

其中,qwebchannel.js 取自 Qt安装目录的 Qt5.12.0\Examples\Qt-5.12.0\webchannel\shared 目录。

2.3 运行

在这里插入图片描述
QT UI加载了html页面,显示了其中的元素。

(1)Web端的getValue获取C++对象的属性navStatus,属性初始值为 “hello”
           在这里插入图片描述
(2)Web端的 callcpp 调用 C++端的函数 function1,C++端function1函数中打出
           在这里插入图片描述
(3)Web端响应 navStatusChanged 事件

3. 使用WebSocket的示例

3.1 C++端代码

3.1.1 mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    ui->setupUi(this);
    // 要导出的类,此类供js调用
    m_myTestClass = new MyTestClass(this);
    // 创建QWebChannel,把创建的类注册到QWebChannel中,js才能调用此类的方法
    m_webChannel = new QWebChannel(this);
    m_webChannel->registerObject("mytestclass", m_myTestClass);
    // js与C++通信方式二、创建QWebsocketServer,web端与之建立连接
    startServer();
MainWindow::~MainWindow()
    delete ui;
// 建立WebSocket服务
void MainWindow::startServer()
    m_websocketServer = new QWebSocketServer("testWebchannel", QWebSocketServer::NonSecureMode, this);
    if(!m_websocketServer->listen(QHostAddress::Any, 12345))
        qDebug() << "websocket server listen failed, error: " << m_websocketServer->errorString();
        return;
    connect(m_websocketServer, &QWebSocketServer::newConnection, this, &MainWindow::onNewConnection);
    qDebug() << "startServer";
void MainWindow::onNewConnection()
    QWebSocket* client = m_websocketServer->nextPendingConnection();
    qDebug() << (QString("Homay robot server has new connection from %1.%2").arg(client->peerAddress().toString()).arg(client->localPort()));
    auto pTransport = new WebSocketTransport(client);
    // 可以不需要,这里只是为了调试打印js端的qwebchannel.js是怎么和C++端通信的,通信协议是什么样的
    connect(pTransport, &WebSocketTransport::messageReceived, this, &MainWindow::onTransportMessageReceived);
    m_webChannel->connectTo(pTransport);
void MainWindow::onTransportMessageReceived(const QJsonObject &message, QWebChannelAbstractTransport *transport)
    qDebug() << "onTransportMessageReceived: " << message;

导出类 MyTestClass,供js调用。
代码中 WebSocketTransport 类代码,取自 Qt安装目录的 Qt5.12.0\Examples\Qt-5.12.0\webchannel\shared 目录下的 websockettransport.h websockettransport.cpp
此处省略。

3.2 Web端代码

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
    <button id="callcpp" onclick="callcpp()">callcpp</button>
    <button onclick="getValue()">getValue</button>
    <script src="qwebchannel.js"></script>
    <script type="text/javascript">
        var webObj;
        // 连接c++端的 Websocket
		var socket = new WebSocket('ws://127.0.0.1:12345');
        // 连接成功后
        socket.onopen = function(){
            alert("onopen");
            // 创建Webchannel
            new QWebChannel(socket, function (channel) {
                // 获取类的对象
                webObj = channel.objects.mytestclass;
                // 类的事件
                webObj.navStatusChanged.connect(function(arg){
                    alert("navStatusChanged: " + arg);
                });
            });
        function callcpp(){
            // 类的方法
            webObj.function1('this is a test');
        function getValue(){
            // 类的属性值
            var status = webObj.navStatus;
            alert(status);
    </script>
</body>
</html>

与2.2中的Web端代码相比,此时,需要先创建WebSocket连接,把socket传入QWebChannel中。

3.3 运行

(1)运行C++, C++代码没有加载html, 此时为空界面;
(2)使用Chrome浏览器,或者Edge浏览器打开Web测试网页,一打开就与C++端的websocket连接上了
           在这里插入图片描述
(3)接下来与2.3的演示一样。

3.4 问题

我这里端口用的12345,可能在有些电脑上此端口被占用了,会报错:
在这里插入图片描述
在这里插入图片描述

改一下端口号就好了, 比如我改成:
在这里插入图片描述

4. 代码

所有代码详见:QWebChannel

业务逻辑实现 QT WebSocket + QWebChannel 实现 C/C++javascript通信 界面使用前electron + vue + vite + layui + qwebchannel.js 实现 qt子进程自动启动,websocket Client自动重连,C++js/ts的双向异步通信,快速开发 博文地址:https://editor.csdn.net/md/?articleId=125851497
业务逻辑实现 QT WebSocket + QWebChannel 实现 C/C++javascript通信 界面使用前electron + vue + vite + layui + qwebchannel.js 实现 qt子进程自动启动,websocket Client自动重连,C++js/ts的双向异步通信,快速开发 博文地址:https://editor.csdn.net/md/?articleId=125851497
QtJavaScript使用QWebChannel交互一——和Qt内嵌网页交互 文章目录QtJavaScript使用QWebChannel交互一——和Qt内嵌网页交互前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 Qt提供了QWebChannel来和网页进行通信,只需要注册一下,就可以直接绑定信号槽来进行Qt程序和网页之前的通信,非常方便 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了
今天是国庆节的第四天,看看书了哦,目前是收集看到的资料的链接,还没有形成自己的理解,先把链接放在这存一下(哈哈哈) Qt中的信号和槽详解_徐kun按门铃的博客-CSDN博客【了解QT里面的一些知识】 1. 语言:PyQt是用Python编写的,而C++ Qt是用C++编写的。 2. 开发难度:C++ Qt的开发难度比PyQt高,因为C++是一门面向对象的编程语言,它需要更多的代码来实现同样的功能。 3. 可移植性:PyQt是跨平台的,它可以在Windows、MacOS和Linux等操作系统上运行,而C++ Qt则只能在支持C++的操作系统上运行。 4. 社区支持:C++ Qt有更为丰富的社区支持,因为它是一门广泛使用的编程语言,而PyQt则相对较少。 总之,PyQtC++ Qt都是强大的图形用户界面(GUI)开发工具,选择哪个工具取决于开发人员的技能水平和项目需求。