Qtブログ(日本語)

Qt for WebAssembly

作成者: 鈴木 佑|Sep 19, 2018 5:07:49 PM

この記事は The Qt BlogQt for WebAssembly を翻訳したものです。
執筆: Lorn Potter, 2018年05月22日

Qt Project が Qt for WebAssembly テクノロジープレビューのベータ版をリリースしたニュースをご覧いただけましたでしょうか。

ウェブサーバーで配信した Qt をウェブブラウザ上で動かすために Emscripten を利用してコンパイルをしています。複数のプラットフォーム向けにコンパイルとデプロイをする代わりに、WebAssembly をサポートするすべてのブラウザむけのウェブサーバー向けにコンパイルとデプロイをするという発想です。これから事業を始める方で、様々なプラットフォームを持つ複数の顧客と仕事をする方は、Qt for WebAssembly で Qt もしくは Qt Quick のアプリをコンパイルすることで、デプロイを一度で済ませることが可能になります。

Qt for WebAssembly のビルド手順は Qt for WebAssembly の wiki ページ をご覧ください。まず初めに、emsdk compiler のダウンロードとセットアップが必要です。手順自体は極めて一般的です。これをクロスコンパイラとして利用します。

開発/デバッグ

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:

Qt Base と QtDeclarative の ‘wip/webassembly’ ブランチ以外にも、以下のモジュールの動作を確認しています。

  • QtCharts
  • QtGraphicalEffects
  • QtQuickControls
  • QtQuickControls2
  • QtWebSockets
  • QtMqtt(websockets のサンプルの WebSocketIODevice を利用します)

QtMqtt を利用する場合は、QtMqtt モジュールの websocketsubscription のサンプルに含まれる WebSocketIODevice クラスを自分のアプリに移植する必要があります。

モバイル(やラップトップ)での画面を縦や横といった向きの変更を扱うための QtSensors のバックエンドのマージリクエストとしてコンパイルだけ確認をしたものが存在しますが、テスト自体はまだ為されていません。

Qml clocks:

JavaScript と WebAssembly にはスレッドが一つしかないため、QtDeclarative は1つのスレッドで動作するようになっています。

textinsgnode:

 

QtCharts, QtGraphicalEffects, QtQuickControls, QtQuickControls2 は変更なしで動作しました。

QtCharts オシロスコープ:

IoT センサーデモ

クリップボードのサポートに関するマージリクエストが存在しますが、現時点ではまだ完璧ではありません。単純なテキストのみ対応しています。

まだ動いていないものたち QTBUG-63917

  • マルチスレッド QTBUG-64700
    • QThread のスタブが存在しています
    • Spectre の脆弱性のため、ブラウザで無効化されています
  • QtNetwork のほぼすべて QTBUG-63920
    • JavaScript のサンドボックスに起因する DNS ルックアップの禁止
    • 単純な QNAM のリクエストは動作するはず
  • ローカルのファイルシステムへのアクセス QTBUG-67834
  • 永続的な QSettings、同期のためかなり遅い。非同期対応 QTBUG-63923
  • QOpenGLWIdget QTBUG-66944
  • Opengl がフルスクリーンでしか動かない QTBUG-67717
  • シェーダーの問題 QTBUG-67338
    • QResource が Qt 自体に埋め込まれたシェーダーを見つけられない
  • exec loop がその他のプラットフォーム同様には機能しない QTBUG-64020
    • exec() イベントループは想定のとおりには終了しない
    • モーダルダイアログのリターン値は動かないが、非モーダルでシグナルと show() を使うことで対処は可能。モーダルのダイアログ/ウィンドウは要対応。
  • toUpperCase QTBUG-66621
  • QClipboard QTBUG-64638

サンプル