2025年5月19日 星期一

Streamlit 學習筆記 : 使用者輸入元件 (三) 核取方塊

本篇旨在測試使用者輸入元件之核取方塊 (checkbox), 此為複選元件, 實際上會渲染為 HTML 中 type 為 checkbox 的 input 元件. 

本系列所有測試文章參考 :


呼叫 Streamlit 的 checkbox() 函式並傳入 label 參數參數即可建立一個核取方塊元件, 勾選它時傳回 True, 否則傳回 False, 其參數結構如下 : 

st.checkbox(label, value=False, key=None, help=None, on_change=None, args=None, kwargs=None, disabled=False, label_visibility="visible") 

參數說明如下表 :


 st.checkbox() 之參數  說明
label 顯示在勾選框旁的文字,為必填參數。
value 初始是否勾選,預設為 False。
key 為元件指定唯一鍵值,避免與其他元件衝突。
help 滑鼠懸停在元件上時顯示的提示說明。
on_change 當勾選狀態改變時,要呼叫的函式。
args 傳入 on_change 回呼函式的位置參數 (tuple)。
kwargs 傳入 on_change 回呼函式的關鍵字參數 (dict)。
disabled 設為 True 時此元件無法互動,呈現灰色。
label_visibility 控制 label 的可見度,可設為 "visible"、"hidden"、或 "collapsed"。


例如 : 


測試 1 : 單一核取方塊只傳入必要參數 label [看原始碼] 

# st-checkbox-test-1.py
import streamlit as st

label='接受全部 Cookies'
checked=st.checkbox(label)
if checked:
    st.write("您已勾選同意接受全部 Cookies")

核取方塊預設為勾選, 因此傳回值為 False, 不會顯示已勾選訊息; 勾選後 checked 傳回值為 True, 這時就會顯示已勾選訊息, 結果如下 :




上面是勾選前, 下面為勾選後. 如果想要一開始就已勾選, 則要傳入 value=True 參數, 例如 :


測試 2 : 用 value=True 設定預設已勾選 [看原始碼] 

# st-checkbox-test-2.py
import streamlit as st

label='接受全部 Cookies'
checked=st.checkbox(label, value=True)
if checked:
    st.write("您已勾選同意接受全部 Cookies")

這樣網頁一初始化預設就已勾選了 :




呼叫多次 st.checkbox() 可建立多選的核取方塊, 例如 :


測試 3 : 多選的核取方塊 [看原始碼] 

# st-checkbox-test-3.py
import streamlit as st

st.subheader('擅長的程式語言 :')
prog1=st.checkbox('Python', value=True)
prog2=st.checkbox('C++')
prog3=st.checkbox('Javascript', value=True)
prog4=st.checkbox('PHP', value=True)
st.write('已勾選項目 :')
if prog1:
    st.write('Python')
if prog2:
    st.write('C++')
if prog3:
    st.write('Javascript')
if prog4:
    st.write('PHP')

此例為每個選項分別呼叫 st.checkbox() 建立核取方塊, 然後用 if 判斷是否傳回 True, 是的話就輸出被勾選的選項, 結果如下 : 




左邊是預設勾選了 3 項, 右邊是取消勾選 PHP 與 Javascript 的結果. 

注意, 與 HTML 中 type=checkbox 的 input 核取方塊元件不同的是, st.checkbox() 所建立的每一個核取方塊都是獨立個體, 它們並沒有 HTML 用相同的 name 去組成一個 group 的概念. 但我們可以用選項字典搭配 Streamlit 的跨執行紀錄狀態字典 st.session_state 來達成群組化功能, 上面的範例改寫如下 : 


測試 4 : 群組化的多選的核取方塊 [看原始碼] 

# st-checkbox-test-4.py
import streamlit as st

st.subheader('擅長的程式語言 :')
options={  # 定義核取方塊選項字典
    'prog1': 'Python',
    'prog2': 'C++',
    'prog3': 'Javascript',
    'prog4': 'PHP'
    }
# 初始化跨執行紀錄狀態字典鍵 programs
if 'programs' not in st.session_state:  
    st.session_state.programs=set()  # 用集合記錄被勾選之項目(避免重複)
for key, lang in options.items():  # 走訪選項字典
    checked=st.checkbox(lang, key=key)  # 建立核取方塊選項
    if checked:
        st.session_state.programs.add(lang)  # 被勾選語言加入集合
    else:
        st.session_state.programs.discard(lang)  # 取消勾選就移除
checked_items=', '.join(st.session_state.programs)  # 組成字串
st.write(f'已勾選項目 : {checked_items}')

此例將核取方塊之選項放在 options 這個以 prog? 為鍵的字典中, 並於 t.session_state 這個跨執行紀錄狀態字典建立一個鍵 programs 來記錄被勾選之項目, 其值為一個字典, 這樣就可以避免重複. 然後用迴圈走訪選項字典 options 來建立核取方塊元件, 此處為了避免 widget 狀態互相干擾, 每次呼叫 st.checkbox() 都有傳入 key 參數 (Streamlit 預設用 label 當 key, 若 label 重複就會產生狀態干擾問題), 此例 label 皆不同, 不設定 key 也是可以的. 結果如下 :




參數 on_change 用來指定選取/取消選取事件發生時的處理函式, 可以搭配 args 傳送參數給處理函式, 如下面範例所示 : 


測試 5 : 利用 args 傳送引數給 on_change 事件處理函式 [看原始碼] 

# st-checkbox-test-5.py
import streamlit as st

def on_checked(lang):
    if st.session_state[f'prog_{lang}']:  # 檢查 key 之值
        st.write(f'{lang} 被選取了')
    else:
        st.write(f'{lang} 被取消選取了!')

st.subheader('擅長的程式語言 :')
langs=['Python', 'C++', 'JavaScript', 'PHP']
for lang in langs:
    st.checkbox(
        label=lang,
        key=f'prog_{lang}',
        on_change=on_checked,
        args=(lang,)
        )

此例以迴圈走訪 langs 串列來建立核取方塊元件, on_change 參數指定選取/取消選取時的事件處理函式 on_checked(), 它會攜帶由 args 元組指定的引數, 在 on_checked() 函式中用位置參數 lang  來接收此引數. key 參數則用來設定此元件獨一無二的鍵以便 st.session_state 字典能紀錄其狀態 (key 為鍵, 值為元件傳回值 True/False), 結果如下 : 




左邊是勾選 C++ 結果, 右邊是取消 Javascript 的結果. 

上面範例也可以改用 kwargs 傳送參數, 例如 : 


測試 6 : 利用 kwargs 傳送引數給 on_change 事件處理函式 [看原始碼]

# st-checkbox-test-6.py
import streamlit as st

def on_checked(lang=None):
    if st.session_state[f'prog_{lang}']:  # 檢查 key 之值
        st.write(f'{lang} 被選取了')
    else:
        st.write(f'{lang} 被取消選取了!')

st.subheader('擅長的程式語言 :')
langs=['Python', 'C++', 'JavaScript', 'PHP']
for lang in langs:
    st.checkbox(
        label=lang,
        key=f'prog_{lang}',
        on_change=on_checked,
        kwargs={'lang': lang}
        )

此例 lang 為關鍵字參數, 因此 on_checked() 中要傳入 lang=None 預設值, 結果如下 :



沒有留言 :