You may have seen the news that Qt Project released Qt for WebAssembly tech preview. (You can now Try Qt for WebAssembly for Free today. Try the latest Qt here.)

We use Emscripten to compile Qt into something that runs in a web browser from a web server. Instead of compiling and deploying for multiple platforms, the idea is to compile and deploy on a web server for any platform that has a browser that supports WebAssembly. If you are an enterprise and have multiple clients that have various platforms in use, you could use Qt for WebAssembly to compile your Qt or Quick app and deploy once.

Qt for WebAssembly build instructions are listed on Qt for WebAssembly wiki. You will first need to download and setup the emsdk compiler. It’s fairly trivial to do. We use this as the cross-compiler.

Developing/Debugging

Debugging is a bit arcane as there is no gdb, but there are output statements (std::cout, qDebug and printf) as well as the debugger console in the browser. You might also have to increase the Web console log limit with (Firefox) "devtools.hud.loglimit.console" from about:config.

To set a breakpoint, add

EM_ASM({ debugger });

into your code to popup the browser debugger. (Don't forget to #include <emscripten.h>) The downside is that you need to recompile.

Screenshots

Not everything works perfectly, but here are some screenshots of a few working examples:

collidingmice:

Standarddialogs: showing multiple windows

QOpenGLWindow works and seems to get near 60 fps. Although they are 'full screen' windows currently, which means they will take up the full browser window. QOpenGLWidget still has some issues. Some shaders seem to have some issues.

Emscripten translates OpenGL calls in WegGL, so there are limitations from the desktop and embedded versions.

Openglwindow:

Besides QtBase and QtDeclarative that use the ‘wip/webassembly’ branch, Qt modules known to work are:

QtCharts

QtGraphicalEffects

QtQuickControls

QtQuickControls2

QtWebSockets

QtMqtt (using WebSocketIODevice from the websockets example)

To use QtMqtt, you will need to integrate the WebSocketIODevice class from the websocketsubscription example in QtMqtt into your app.

There is also a WIP MR for a backend to QtSensors for orientation changes on mobiles (including laptops) that I have thrown together which compiles, but hasn’t been tested.

Qml clocks:

Since javascript and webassembly have only one thread, QtDeclarative was made to work with only one thread.

textinsgnode:

QtCharts, QtGraphicalEffects, QtQuickcontrols, QtQuickControls2 all work without changes.

QtCharts oscilloscope:

IoT sensor demo showing demo data

There is a WIP merge request for clipboard support, but it is unfinished at this time. It is working for simple text.

Things that don't work QTBUG-63917

Multithreading QTBUG-64700 there is a stub QThread disabled in the browsers due to the Spectre vulnerability

Most QNetwork QTBUG-63920 no DNS lookups due to javascript sandbox simple QNAM requests should work.

Local Filesystem access QTBUG-67834

persistent QSettings, it syncs the config rather slow and asynchronously QTBUG-63923

QOpenGLWIdget QTBUG-66944

Opengl only works fullscreen QTBUG-67717

some shaders QTBUG-67338 QResource fails to find shaders built-in to Qt

The exec loop does not function like other platforms QTBUG-64020 exec() event loop will not return where you expect it to Returning values from modal dialogs are known not to work but can be worked around by using non-modal signals and show(). Although modal dialogs/windows will still open.

toUpperCase QTBUG-66621

QClipboard QTBUG-64638

Examples