Html网页和C++ App通信 - qwebchannel

7 篇文章 0 订阅

Qt5 引入了 Qt WebChannel 的概念。这是为了在不能影响各端代码执行的前提下实现 Qt 端于 client 端的无缝 双向 通信。
QWebChannel 提供了在 C++应用和 前端(HTML/JS)之间点对点的通信能力。通过向 前端的 QWebChannel 发布 QObject 的 派生对象,进而实现在 前端无缝读取来自 Qt 端的 公共插槽 和 QObject 的 属性值 和 方法。在整个通信过程中,无需任何手动序列化传入的参数。所有 Qt 端的 属性 更新,signal 触发,都会 自动且异步 更新到 前端。

QObject 是 Qt 中对象模型的核心。该模型的核心特性是被称为 signal 和 slot 的对象通信机制。

要实现 client 端的 QWebChannel,必须引入 Qt 官方提供的 qwebchannel.js 的 JS 库。该库的目的在于封装了一系列的 通信接口 和传输信息时的序列化信息的方法。

1. 在HTML网页中,调用C++代码,执行指定功能(如,print)

HTML通过JavaScript调用C++方法,需要建立qwebchannel通道。qwebchannel类的官方描述如下:

The QWebChannel fills the gap between C++ applications and HTML/JavaScript applications. By publishing a QObject derived object to a QWebChannel and using the qwebchannel.js on the HTML side, one can transparently access properties and public slots and methods of the QObject. No manual message passing and serialization of data is required, property updates and signal emission on the C++ side get automatically transmitted to the potentially remotely running HTML clients. On the client side, a JavaScript object will be created for any published C++ QObject. It mirrors the C++ object’s API and thus is intuitively useable.
The C++ QWebChannel API makes it possible to talk to any HTML client, which could run on a local or even remote machine. The only limitation is that the HTML client supports the JavaScript features used by qwebchannel.js. As such, one can interact with basically any modern HTML browser or standalone JavaScript runtime, such as node.js.

有两种情况:
1). 如果前端代码中已经嵌入了qwebchannel.js,需要在C++中创建 channel并且注册一个通信的对象,并设置到网页中。

    QWebChannel*_channel = new QWebChannel(this);
    _channel->registerObject(QStringLiteral("printManager"), MSBrowserMainView::m_pManager);
    page()->setWebChannel(_channel);

PS. 如何判断网页有没有嵌入qwebchannel.js?
用 Chrome浏览器打开该网页,并按F12键打开开发者模式,ctl+F搜索qwebchannel.js
在这里插入图片描述
2). 如果前端没有嵌入qwebchannel,需要在C++代码中把qwebchannel.js加载进网页。
在网页构造函数中创建channel,把要用到的对象注册进去,并加载到网页中:

    m_webChannel = new QWebChannel(this);
    m_webChannel->registerObject("webView", this);
    page()->setWebChannel(m_webChannel);

在合适的地方(确保网页加载完成之后)执行qwebchannel.js把qwebchannel加载进网页

    QFile file;
    QString webChannelJsApi = "";
    file.setFileName("../homepage/js/qwebchannel.js");
    if(file.exists())
    {
        file.open(QIODevice::ReadOnly);
        webChannelJsApi = file.readAll();
        file.close();
    }
    page()->runJavaScript(webChannelJsApi);

加入JavaScript代码,修改网页某个指定button的回调函数,让它执行C++代码:

   //handle the click event for the printer button.
    QString btClickCode = QStringLiteral("var oBtn=document.getElementsByTagName('button')[3];" \ // 这里需要跟前端约定好指定的button。
                                         "oBtn.οnclick=function(){" \
                                         "window.channel = new QWebChannel(qt.webChannelTransport,function(channel){" \
                                         "var webobj = channel.objects.webView;" \ // webView is the id of WebView, see registerObject(id, *obj)
                                         "webobj.printWebPage();" \ //printWebPage() is a C++ method in WebView class
                                         "});" \
                                         "}" \
                                        );
    page()->runJavaScript(btClickCode);

2. 在C++代码中插入Javascript代码,操作网页。

单纯地在C++中插入一段JavaScript代码,执行前端的方法,不需要建立通道。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值