WebUIはデスクトップアプリを作るためのライブラリ。HTML, CSS, JavaScriptでフロントエンドを作り、バックエンドをC, C++, Python, Go, TypeScriptなどの言語で開発できる。システムにインストールされているWebブラウザで動作する
2023年にhassandragaさんが公開し、V言語コミッタのttytmさんらも参加した
本体はCで開発されていて、Python, Go, TypeScriptにバイディングが提供されている
似た技術としてはElectronやTauri、Gluonなどが存在する
アーキテクチャについて
ElectronやTauriと比較すると、WebUIのアーキテクチャはWebアプリをブラウザで開くだけなのでより単純かつ制約が大きい
開発者にとってはブラウザを使ってプログラムにGUIを付けられるライブラリであり
ユーザーにはChromeのdesktop shortcutsのようにスタンドアロンなウィンドウで起動するWebアプリになる
他のフレームワークとの簡単な比較図を作った
Presentation | Main Program | Bridge | |
---|---|---|---|
Electron | Chromium | Node.js | IPC |
Tauri | WebView | Rust | IPC(JSON-RPC) |
WebUI | Web Browser | C and bindings | HTTP(WebSocket) |
WebUIでデスクトップアプリを起動する時のフローが以下になっている
- Pythonなどで記述したMainプログラム(hello_world.py)を実行
- WebUIがシステムにインストールされているウェブブラウザを呼び出す
- 専用のプロファイルでMainプログラムが実行する
http://localhost:53949
を開いてデスクトップアプリっぽく見せる
git clone https://github.com/webui-dev/python-webui cd python-webui/examples pip install webui2 python hello_world.py
MyWindow = webui.window() MyWindow.show(login_html) # 描画するHTMLのテキスト
このデスクトップアプリのシステムWindowは「Google Chrome」になっていて以下のプロセスで実行されている
ps x | grep .WebUI /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --user-data-dir=/Users/laiso/.WebUI/WebUIChromeProfile --no-first-run --no-proxy-server --safe-mode --disable-extensions --disable-background-mode --disable-plugins --disable-plugins-discovery --disable-translate --disable-features=Translate --bwsi --disable-sync --disable-sync-preferences --disable-component-update --allow-insecure-localhost --app=http://localhost:53949
Mainプログラムとブラウザのブリッジ連携
Mainプログラム側からブラウザの値を参照するにはJavaScriptコードを送る
res = e.window.script("return document.getElementById(\"MyInput\").value;") if res.data == "123456": print("Password is correct.")
逆にブラウザ側からMainプログラムの関数を呼び出す時はwindows.webui
オブジェクト経由でバインドしておく
def check_the_password(e : webui.event): #... MyWindow.bind('CheckPassword', check_the_password)
<button onclick="webui.CheckPassword()">Check Password</button>
もしくはHTMLのid要素に暗黙的にバインドされている
<button id="CheckPassword">Check Password</button>
これを使うためにHTML側には <script src="webui.js"></script>
のおまじないが入ってないといけない
この中身がwebui /bridge/で、TypeScriptで書いたWebSocketクライアントをさらにCのヘッダにhexにして埋め込んでいる
埋め込んだ文字列をローカルサーバーの /webui.js
として返している
なんでそんなことを…… と最初思ったが、バイナリに埋め込み静的ライブラリとして配布するため?
その他の特性
- あくまでライブラリでデスクトップアプリを配布用にパッケージングする仕組みなどはない
- 例えばMainプログラムの実行にPythonが必要なら利用する環境にもインタプリタがないといけない
- ブラウザの中で動いているローカルなWebアプリなので、その外側のOSの機能(システムメニューなど)まではアクセスできない
ドキュメントは https://webui.me/docs/
Disclaimer
この記事はWebUIのコア実装の理解に焦点を置いています。ElectronやTauriと比較し、WebUIの利用を薦めるものではありません
筆者はデスクトップアプリの開発にはプラットフォームの標準SDKを使います