有关Qt的WebEngine模块与JS交互的研究



  • 0_1524455491639_444.png
    最近几年Web和桌面混合应用逐渐流行起来,Qt也顺应形势,在2014年12月推出了WebEngine模块。它的作用就是让开发桌面/WEB混合应用程序更加方便。之前我了解了一些WebEngine的内容,也做了一些小的demo,但是直到前些日子,我对WebEngine强大的功能了解一点点。一些特殊的场景依然需要开发者更加努力完善才行,比如说:

    1. 浏览器和桌面应用的交互
      通过点击浏览器的内容转到桌面特定的功能或者点击桌面的菜单启动浏览器并且进行一些设置,这些需要涉及到WebEngine和Javascript交互的知识;
    2. 为浏览器添加特定的插件以便在输入含有特定的scheme的时候,启动本地相关的功能。比如ed2k://这样的链接。这里要涉及到一个浏览器的URL处理handler这样的处理步骤。

    现在很多的软件都支持内置网页,比如说迅雷软件,还有WPS,这些都支持在内部载入浏览器。也很好地实现了“软件+内容”的统一处理。带着这些问题,我们也尝试着了解WebEngine,并且使用WebEngine来实现相应的功能。



  • 一个非常常见的需求就是需要满足WebEngine中的html元素和Qt的其它元素的交互。因为如果只套了WebEngine,数据只在Chromium中的v8引擎中流动,和Chrome浏览器无异。我们软件的开发主要看重的是和其它的程序进行联动。比如说软件内链接可以本地启动一个轻量级的浏览器,或者浏览器的内容点击可以让本地程序进行响应。这一部分我想是WebEngine精髓的地方,好在Qt团队想到了这一点,可以使用WebChannel这个模块来实现这样的目的,和以前操作QtWebkit那一套不同,使用WebChannel通过信号和槽将WebChannel和本地C++对象连接起来,通过JS的事件机制将WebChannel和JS对象连接起来,从而建立了联系,这样做有利于解耦C++和WebEngine,让其具有更大的可操作移植性。

    好了,开始拿官方的例子做研究了,我们选择先从WebChannel入手,查看官方的例子:standalone
    0_1524384025356_d8484c85-83e0-4a1e-a000-bc9f6a0aed5d-image.png

    我们发现它包含了几个文件:

    core.h
    core.cpp
    dialog.h
    dialog.cpp
    main.cpp
    shared/qwebchannel.js

    值得注意的是qwebchannel.js文件,它以模块化的方式在js前端(或者后端)搭建了桥梁,让Qt对象通过传输协议(很大程度上是websocket)暴露在js中并且得以使用。

    例子也较为简单,通过客户端建立本地的QWebSocketServer来监听12345端口,并且让客户端的QWebSocket和浏览器的WebSocket(原生)同时监听localhost:12345端口。这样可以实现双端通信。值得注意的是,客户端和网页端都使用了WebChannel来建立起联系——客户端使用的是WebChannel的C++接口方法,而网页端使用的是qwebchannel.js方法。
    0_1524385057615_8431ace6-5420-48d6-bd88-b6f124985529-image.png

    这个例子简单展示了WebChannel的使用,但我认为此处的WebChannel其实是多余的,只通过WebSocket就可以建立客户端和网页的连接。



  • 每次都想用html写界面,然后后台用C++。
    但是Qt WebEngine总是用不好
    有个叫CEF的东西,好像用的人挺多的



  • @大黄老鼠 我也考察了cef。主要是cef这块儿有三点:

    1. 下载需要翻墙,如果没有梯子的话,都没办法下载下来。
    2. 文档较少,我能知道的文档主要来自于博客介绍。
    3. 如果是自己制作软件嵌入浏览器,可能选择MFC + cef、Qt + cef,或者是其它基于各种语言的库 + cef。如果要处理多进程的问题,还是需要非常具有经验的开发者才行。简而言之,学习门槛稍微高。

    WebEngine慢慢在发展,一些以前没有暴露的接口现在已经暴露出来了。而且有Qt公司的维护,我想至少作为入门是没有问题的。

    他们俩都不好的地方就是库太大了。随随便便就是50M以上。


Log in to reply
 

走马观花

最近的回复

  • C

    Qt for MCU需要商业授权的

    read more
  • Qt for MCUs

    搭建Qt for MCUs PC端开发环境。qt for mcus提供了一个完整的图形框架和工具包,包含了在MCUs上设计、开发和部署gui所需的一切。它允许您在裸机或实时操作系统上运行应用程序。

    先决条件

    开发主机环境支持仅限于Windows 10

    MSVC compiler v19.16 (Visual Studio 2017 15.9.9 or newer) x64

    CMake v3.13 or newer (you can install it using the Qt Online installer) x64

    使用Qt联机安装程序安装Qt for MCUs,该安装程序可通过Qt帐户下载

    安装Qt 5.14和Qt Creator 4.11 or higher

    安装链接

    › Qt: https://account.qt.io/downloads
    › CMake: https://cmake.org/download/
    › Python 2.7 32-bit: https://www.python.org/downloads/release/python-2716/
    › Arm GCC: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnutoolchain/gnu-rm/downloads
    › J-Link Software Pack: https://www.segger.com/downloads/jlink/JLink_Windows.exe
    › J-Link OpenSDA Firmware: https://www.segger.com/downloads/jlink/OpenSDA_MIMXRT1050-EVKHyperflash
    › STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html
    › STM32 ST-LINK Utility: https://www.st.com/en/development-tools/stsw-link004.html​​​​​​​

    Qt Creator设置 启用Qt Creator插件 选择“帮助>关于插件”,然后从列表中选择“MCU支持(实验性)”插件,重新启动Qt Creator以应用更改
    替代文字 为MCU创建Qt工具包

    选择工具>选项>设备>MCU

    选择Qt for MCUs-Desktop 32bpp作为目标

    如果尚未设置,请提供Qt for MCUs安装目录的路径。

    单击Apply应用。

    替代文字

    替代文字
    替代文字

    注意:

    编译器要选X64,Qt版本要选64bit,CMake Tool选x64

    打开恒温器项目demo

    选择文件>打开文件或项目。。。

    打开CMakefiles.txt文件来自thermo文件夹的文件。

    选择Qt作为MCU-桌面32bpp套件。

    单击“配置项目”以完成。

    替代文字

    问题

    开发主机环境支持仅限于Windows 10

    C++编译失败,文本大字体.pixelSize.

    文本类型无法正确呈现需要复杂文本布局的unicode序列。对复杂文本使用StaticText

    read more
  • H

    hi 有问题请教你,方便加个联系方式吗

    read more
  • boost.asio是一个很棒的网络库,这回儿我也开始系统地学习起来了。想想当年接触boost,也有八年多了。这次开始接触boost,觉得既熟悉又陌生。熟悉的是小写字母+下划线的命名方式、晦涩的模板、很慢的编译速度以及较大的程序体积,陌生的是asio的各种概念:io服务、接收器、套接字等等:我之前对网络编程不是非常了解。

    于是根据我的理解,参考《Boost.Asio C++网络编程》实现了这样一个简单的客户端和服务端通信的例子,例子非常简单,还不完善,但是幸运的是,可以在本机上互通了。
    下面是客户端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void writeHandler( const boost::system::error_code& ec, size_t bytesTransferred ) { if ( ec ) { cout << "Write data error, code: " << ec.value( ) << "transferred: " << bytesTransferred << endl; } else { cout << "OK! " << bytesTransferred << "bytes written. " << endl; } } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::socket sock( service ); ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; sock.connect( ep, ec ); if ( ec ) { cout << "Connect error, code: " << ec.value( ) << ", We will exit." << endl; return ec.value( ); } else { char buf[1024] = "Hello world!"; sock.async_write_some( buffer( buf ), writeHandler ); sock.close( ); } return service.run( ); }

    下面是服务端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void acceptHandle( const boost::system::error_code& code ) { cout << "Accepted." << endl; } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; ip::tcp::socket sock( service ); ip::tcp::acceptor acceptor( service, ep ); acceptor.async_accept( sock, acceptHandle ); if ( ec ) { cout << "There is an error in server. code: " << ec.value( ) << endl; } return service.run( );// 阻塞运行 }

    运行结果是这样的:
    78448d7b-b3ae-42fc-9e2e-4dd2fbdac2c2-image.png

    我对boost.asio中几个概念的理解:

    io_service,这就是一个类似事件循环的东西,它为io设备提供服务,故名。不管是套接字、文件还是串口设备,都要使用它的服务。它的run()函数相当于启动了一个事件循环。一旦有消息了,即进行响应。这也是实现异步编程的重要基础。 socket,这个类则是套接字,可以处理TCP或者是UDP请求。有同步以及异步的处理方式,也有带异常以及不带异常的处理方式。 acceptor,接收器,仅仅是服务端使用。相当于其余框架中的listener,作接收用的。

    比较浅显,如果有不当之处,敬请指正。

    read more

关注我们

微博
QQ群