Qt for WebAssembly

作者:Richard Lin | Oct 12, 2018 6:12:46 AM

原文作者:Lorn Potter ,自由开发者,之前曾经在Trolltech、Nokia、Jolla、Canonical和Intopalo工作。在Qt Project中,担任QSensors和QSystemInfo模块的维护者,还参与了QBearerManagement的工作。

校审:Richard Lin

 

您可能已看到Qt 开源项目发布Qt for WebAssembly 技术预览版这则消息。

我们用 Emscripten 把Qt编译成可以从web服务器下载到浏览器中运行的形式。我们的目标是能为任何安装了支持WebAssembly浏览器的平台编译、部署Qt应用到web服务器上,不再需要编译、部署到多个系统。如果您是企业用户,并有多个同时运行各种平台的客户端,您可以使用Qt for WebAssembly来编译您的Qt或Quick程序,只要部署一次即可。

Qt for WebAssembly的搭建指导说明参请见 Qt for WebAssembly wiki 。首先,您需要下载并安装 emsdk编译器。过程有点琐碎,它是我们的交叉编译器。

开发/调试

调试过程有些麻烦,因为浏览器中没有gdb,但是会有状态输出(std::cout,qDebug以及printf)以及浏览器的调试控制台。您可能还需要把网页控制台记录行数上限调高,通过(Firefox)在about:config页面中修改“devtools.hud.loglimit.console”。

在代码中添加

EM_ASM({ debugger });

可以弹出浏览器调试器,作为设置断点的手段。(别忘了#include<emscripten.h>)。不方便的是您需要重新编译。

屏幕截图

不是所有都能完美运行,但以下是一些成功运行示例的屏幕截图:

collidingmice:

Standarddialogs:显示多窗口

QOpenGLWindow能够运行,并且接近60fps,尽管现在它们是“全屏”,也就意味着它们将占据整个浏览器窗口。QOpenGLWidget仍然有一些问题,有些着色器看上去有些问题。

Emscripten把OpenGL的调用翻译成WebGL,因此对于桌面和嵌入式版本有一定限制。

Openglwindow:

除了使用‘wip/webassembly’分支的QtBase和QtDeclarative模块,运行顺利的Qt模块还有:

  • QtCharts
  • QtGraphicalEffects
  • QtQuickControls
  • QtQuickControls2
  • QtWebSockets
  • QtMqtt (使用websockets 示例中的WebSocketIODevice)

如果要使用QtMqtt,您需要从QtMqtt的websocketsubscription示例中集成WebSocketIODevice类到您的应用。

还有一个正在开发中(WIP)的合并请求(MR),主要是关于QtSensors模块后台,实现移动端(包括笔记本电脑)的屏幕方向随重力改变功能。它已经编译通过但还需要测试。

QML 时钟:

因为javascript和webassembly只有一个线程,QtDeclarative只能工作在单线程中。

textinsgnode:

QtCharts、QtGraphicalEffects、QtQuickcontrols、QtQuickControls2 都能直接运行、无需改变。

QtCharts示波器:

IoT 传感器demo显示demo数据

有一个正在开发中(WIP)的合并请求,关于剪切板的支持,但是现在它还没有完成。目前只支持纯文本。

无法工作的部分 QTBUG-63917

  • 多线程QTBUG-64700
    • QThread完全失效
    • 浏览器禁用,因为担心容易崩溃/安全漏洞?
  • 大部分QNetwork QTBUG-63920
    • 无法在javascript沙盒中查找DNS
    • 简单的QNAM请求可以运行
  • 本地文件系统读写QTBUG-67834
  • 持久化 QSettings,同步设置文件非常缓慢并且只能异步 QTBUG-63923
  • QOpenGLWIdget QTBUG-66944
  • Opengl只在全屏时工作QTBUG-67717
  • 部分着色器QTBUG-67338
    • QResource 无法找到Qt内置的着色器
  • 执行循环和其他平台上的不一样QTBUG-64020
    • exec() 事件循环不会在你期望的地方返回。
    • 模态窗口返回值无效,但是可以用非模态信号和show()组合绕开这个问题。尽管模态对话框和窗口还是可以打开。
  • toUpperCase QTBUG-66621
  • QClipboard QTBUG-64638

示例

WebAssembly是一种可在网页浏览器中执行的字节码格式,应用程序无需执行独立的安装步骤,就能通过兼容的网页浏览器部署到设备上。应用程序会运行在网页浏览器的安全沙盒中,适合于那些不需要访问完整设备功能、只需便捷简单安装过程的应用。在Qt 5.11中,我们发布了Qt for WebAssembly技术预览版,您可尝试直接在浏览器窗口中运行Qt应用程序。