NiceGUI ネイティブアプリの作成向けTIPS
自分の備忘録としても。ネイティブに限らないけど。
ネイティブモード時のズーム設定について
自分はブラウザの表示設定を大体80%ぐらいにしています(単純に自分の好み)。NiceGUIアプリをWebブラウザで表示させている時はよいのですが、ネイティブモードで動作させると当然100%相当で表示されるので(個人的には)表示が大きくて少し気になる。
左が80%のWebブラウザ表示。右がネイティブモードの表示。
というわけで、pywebviewのJavascriptを実行するAPIを使ってズーム設定を変更します。
app.native.main_window.evaluate_js("document.body.style.zoom = '80%'")
ただ、native.main_window
は ui.run
が呼ばれてからでなければ生成されないので、ui.run
の後に呼ばなくてはならない。かつ Javascriptコードは非同期実行されるので、NiceGUIのエレメントAPIがすでに呼ばれていると、一瞬100%の表示が見えて、そのあとズーム設定が適用されるためツラツキが見えて見栄えが悪い。
なので、
-
app.on_startup
でアプリのスタート時コールバックを設定する -
ui.run
の呼び出し - startupコールバック内でzoom設定の変更 & 完了まち
- startupコールバック内でNiceGUIのエレメント呼び出し
というようにする。
async def onStartup():
// Javascript実行は非同期なので await する
await app.native.main_window.evaluate_js("document.body.style.zoom = '100%'")
// この後にNiceGUIエレメントを呼ぶ
ui.label("Hello world.")
app.on_startup(onStartup)
ui.run(native=True)
ちなみに、
app.native.window_args["zoomable"] = True
を最初に呼んでおけば、ネイティブアプリ上で ctrl+ホイール 操作でも表示倍率を変えられるようになる。
ui.menu
の階層表示について
↓このような階層のあるメニューの作り方
ui.list
は必須ではないけれど、.props("dense")
付きでui.menu_item
を囲むことで各メニュー項目がコンパクトに表示されて美しいです。
with ui.button(icon="menu"):
with ui.menu():
with ui.list().props("dense"):
ui.menu_item("Item 1")
ui.menu_item("Item 2")
ui.separator()
with ui.menu_item("Submenu", auto_close=False).classes(
"items-center justify-between"
):
ui.icon("keyboard_arrow_right")
with ui.menu().props("anchor='top end' self='top start'"):
with ui.list().props("dense"):
ui.menu_item("Subitem 1")
ui.menu_item("Subitem 2")