NiceGUIとは
NiceGUI(https://nicegui.io/) は、Pythonから使用できるGUIライブラリで、バックエンドとしてウェブブラウザを用いる。GUIを起動すると、WebサーバがPythonインタプリタ内に立ち、それに対してWebブラウザからアクセスして利用する。
内部的には大量のJavaScriptのライブラリを持っていて、それを使って描画しているのだろう。ざっと見た限りボタンやラベル、テキストエリア、スライダなど基本的なコンポーネントは揃っているようだ。
線画などの描画はSVGを直接書き込まなければならないようで、ちょっと敷居が高いが、ラッパを作ってやれば良さそう。
Jupyterでの利用
基本的な起動は下のように行う。ui.run()
とやるとそこでイベントループが走る。これはGUIからすべてを操作するようなアプリであればあまり問題ないのだろうが、Jupyterなどで使うとちょっと面倒。セルがブロックしてしまうので他のことが何もできない。
from nicegui import ui
ui.label('Hello NiceGUI!')
ui.run()
対応方法
ぐぐってみたら、こんなのを見つけた。
https://github.com/zauberzeug/nicegui/discussions/733
要するにスレッドを一つ作って、そこでGUIのイベントループを回せばいい。
import threading
from nicegui import ui,app
ui_thread = threading.Thread(target=lambda: ui.run(reload=False))
ui_thread.start()
count = 0
def my_click():
ui.notify("button was pressed")
global count
count += 1
print(count)
ui.label("Hello NiceGUI!")
button = ui.button("BUTTON", on_click=my_click)
この状態で
app.shutdown()
とやるとuiのイベントループが死んで、スレッドも自動的に停止する。すばらしい。
所感
理想的にはJupyterノートブックのなかにUIを表示したいところだけど、隣のタブに表示できればまあいいだろう。
UIを表示した状態で、データをいじってUIに反映させる事もできるが、多分普通にデータ競合が起こる。ちゃんとやるなら排他ロックを書けないといけなさそう。
表示に辞書として表現されるモデルをバインドして、モデルが更新されたら自動的に描画されるようにできるようなので、こちらを使えばいいのかな?