NiceGUI: Python 的 UI 框架,撰寫 Python GUI 的好工具

如果你剛寫好一個 Python 小程式,想要給其他人使用
或是你還在思考要用什麼 UI 框架來包裝你的小程式
那就來試試 NiceGUI 吧!
NiceGUI
某天在找 Python 可以用的 GUI 框架,之前用過 Python 自帶的 Tkinter,雖然寫起來蠻簡單的,但如果沒有特別調過看起來也比較陽春(?),除此之外,也有用過鼎鼎大名的 PyQt 和 PySide,但感覺要寫個小程式的 GUI 要搬出 Qt 總感覺殺雞用牛刀,終於在某次的機緣下看到了 NiceGUI。
NiceGUI 是基於 Python 程式語言的 UI 框架,你可以用 Python 寫出簡單又優雅的介面,NiceGUI 的 GUI 不像是傳統的視窗,而是用網頁的方式呈現,執行後程式後,在瀏覽器打上網址就可以看到介面了,只要有瀏覽器都可以使用,介面上可以放按鈕、文字框、圖片等一般介面會看到的組件。
安裝
目前 NiceGUI 支援 Python 版本 3.7 或以上,可以直接透過 PyPI 安裝,想要用 Docker 的也有官方製作的 Image。
透過 PyPI 安裝:
python3 -m pip install nicegui
使用 Docker:
zauberzeug/niceguidocker pull zauberzeug/nicegui
基本使用
官方提供了簡單的範例,放了一個 label 和一個按鈕,按下按鈕會顯示 button was pressed,最後執行 GUI,執行後會自動開啟瀏覽器並顯示 GUI,如果你更改過程式碼,儲存後會重新整理並顯示更改過後的結果,不用關掉重開,在撰寫的時候十分方便。
from nicegui import ui
ui.label('Hello NiceGUI!')
ui.button('BUTTON', on_click=lambda: ui.notify('button was pressed'))
ui.run()

接下來我們就來介紹幾個常見的用法,其他更進階的用法就請自行參考他們的 document 傳送門。
標籤 (Label)
ui.label
: 放置一個文字 Label- 傳入要顯示的文字。
from nicegui import ui
ui.label("I'm a label.")
ui.run()

按鈕 (Button)
ui.button
: 放置一個按鈕- 傳入要顯示的文字。
- 可以透過
on_click
來設定按下要執行的事件。 color
可以傳入想要的顏色。
from nicegui import ui
ui.button("I'm a Button 1.")
ui.button("I'm a Button 2.", color='red')
ui.button("I'm a Button 3.", color='green', on_click=lambda: ui.notify('clicked'))
ui.run()

通知 (Notify)
ui.notify
: 顯示通知- 傳入要顯示的文字。
- 可以使用
closeBtn
來新增關閉的通知的按鈕。
from nicegui import ui
ui.button("Notify", on_click=lambda: ui.notify('clicked'))
ui.button("Notify (close)", on_click=lambda: ui.notify('clicked', closeBtn='close'))
ui.run()

單選鈕 (Radio Button)
ui.radio
: Radio 按鈕- 用 list 傳入每個選項的文字,或是用 dictionary 傳入每個選項的文字和數值。
- 可以使用
value
來設定初始值。 on_change
可以設定改變時要執行的事件。- 預設是垂直的,但可以透過
props('inline')
來改成水平的
from nicegui import ui
ui.radio([1, 2, 3], value=1)
ui.radio({'A': 1, 'B': 2, 'C': 3}, value='C').props('inline')
ui.radio(['ㄅ', 'ㄆ', 'ㄇ'], value='ㄆ', on_change=lambda: ui.notify('changed', closeBtn='close')).props('inline')
ui.run()

下拉式選單 (Dropdown Selection)
ui.select
: 下拉式選單- 用 list 傳入每個選項的文字,或是用 dictionary 傳入每個選項的文字和數值。
value
: 設定初始值。on_change
: 可以設定改變時要執行的事件。with_input
: 是否可以輸入文字來顯示候選選項。
from nicegui import ui
ui.select([3, 2, 1], value=1)
ui.select({1: 'ㄅ', 2: 'ㄆ', 3: 'ㄇ'}, on_change=lambda: ui.notify('changed'))
ui.select([1, 2, 3], with_input=True)
ui.run()

核取方塊 (Checkbox)
ui.select
: 下拉式選單- 傳入顯示的文字。
value
: 設定初始值,預設是False
。on_change
: 可以設定改變時要執行的事件。
from nicegui import ui
# example 1
checkbox1 = ui.checkbox('Show text')
ui.label('Hi').bind_visibility_from(checkbox1, 'value')
# example 2
ui.checkbox('True by default', value=True)
# example 3
checkbox2 = ui.checkbox('Change Color to Red',
on_change=lambda e: checkbox2.style(f'color:{"red" if e.value else "black"}'))
ui.run()

滑動條 (Slider)
ui.slider
: 顯示滑動條- min: 最小值。
- max: 最大值。
- value: 初始值。
- step: 每次更動一格的數值。
- on_change: 改變時要執行的事件。
以下兩個範例都可以達到根據 slider 的數值來調整顯示的文字。
from nicegui import ui
# example 1
slider = ui.slider(min=0, max=100, value=20, step=5)
ui.label().bind_text_from(slider, 'value')
# example 2
text = ui.label('20')
ui.slider(min=0, max=100, value=20, step=5,
on_change=lambda e: text.set_text(e.value))
ui.run()
文字欄位 (Text Input)
ui.input
: 顯示文字輸入框- label: 欄位顯示的名稱。
- placeholder: 尚未輸入值時顯示的文字,用來提示使用者要輸入的數值。
- on_change: 改變時要執行的事件。
- validation: 驗證輸入的數值。
from nicegui import ui
ui.input(label='Text', placeholder='Please enter the text',
on_change=lambda e: result.set_text(e.value.upper()),
validation={'Input too long': lambda value: len(value) < 10})
result = ui.label()
ui.run()

圖片 (Image)
ui.image
: 顯示圖片
from nicegui import ui
ui.image('https://picsum.photos/1080.webp')
ui.run()

影片 (Video)
ui.video
: 顯示影片
from nicegui import ui
v = ui.video('https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4')
ui.run()

Pyplot 圖表
ui.pyplot
: 畫出 pyplot 的圖表
import numpy as np
from matplotlib import pyplot as plt
from nicegui import ui
# draw a sin curve
with ui.pyplot(figsize=(3, 2)):
x = np.arange(0, 4*np.pi, 0.1)
y = np.sin(x)
plt.plot(x, y, '-')
ui.run()

列 (Row) / 行 (Column)
ui.row
: 擺放在同一列ui.column
: 擺放在同一行
from nicegui import ui
with ui.row():
ui.label('Row 1')
ui.label('Row 2')
ui.label('Row 3')
with ui.column():
ui.label('Column 1')
ui.label('Column 2')
ui.label('Column 3')
ui.run()

Icon
ui.icon
: 顯示 icon- 輸入 icon 的名稱,icon 列表 傳送門。
color
: 顏色。
from nicegui import ui
ui.icon('paid', color='primary').classes('text-5xl')
ui.run()

後記
以上介紹了多種常用到的元件,其他更進階的用法就請自行參考他們的 document 傳送門。
Reference
如果你覺得這篇文章有用 可以考慮贊助飲料給大貓咪