2025年6月1日 星期日

Streamlit 學習筆記 : 容器與版面配置元件 (二) 靜態與動態容器

今天是端午連假最後一天, 繼續快馬加鞭測試 Steamlit 的容器與排版元件. 

本篇旨在測試 Streamlit 的靜態容器 st.container() 與動態容器 st.empty(), 這兩個元件都是不可見的容器 (無框線), 兩者差別在於 st.container() 一旦往裡面添加元件就無法變更與刪除; 而 st.empty() 物件則因為擁有一個 empty() 方法可以清除內容重新添加, 從而具有動態更新內容功能. 


 元件 類型 說明
st.columns()版面建立多欄式佈局,回傳多個可操作的 column 區塊。
st.container()容器建立一個可包含其他元素的區塊 (靜態容器)。
st.empty()容器建立一個暫時的空白位置 (動態容器),可動態更新與清除內容。
st.sidebar容器側邊欄容器,適合放置選單、選項、控制元件等。
st.tabs()版面建立多個分頁頁籤,每個分頁有獨立的內容顯示區域。
st.expander()容器可展開與收合的內容區域,適合隱藏次要資訊。
st.container().columns()混合在 container 中建立欄位,實現更靈活的版面配置。


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


首先測試靜態容器 st.container().


1. 靜態容器 st.container() : 

呼叫 st.container() 函式會建立一個不可見, 用來包裝其他元件的靜態容器, 可在其內放置其它 Streamlit 元件 (內容寫入後固定不可更改). 

st.container() 函式沒有傳入參數, 其傳回值為一個容器類別 DeltaGenerator 的物件, 幾乎所有 st.xxx() 函式的名稱都可以作為此容器物件的方法名稱來呼叫, 這是在容器中添加 Streamlit 的第一個方法 : 

container=st.container()
container.xxx()   # 在容器中加入 st.xxx() 元件

例如 :


測試 1-1 : 在 st.container() 容器中加入元件的方法 (1) [看原始碼]   

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

st.subheader('st.container() 容器元件測試')
st.write('這在容器外')
container=st.container()
container.write('這在容器內')
container.button('這在容器內')
container.info('這在容器內', icon='ℹ️')
st.write('這在容器外')
st.info('這在容器外', icon='ℹ️')

注意, 呼叫 container.xxx() 的都是在容器內, 而呼叫 st.xxx() 的都在容器外, 結果如下 : 




在 st.container 容器中加入元件的第二種方法是使用 with 語法, 這時在 with 區塊內要呼叫 st.xxx() 函式來加入元件而非 st.container().xxx() :

with st.container():
    st.xxx()

例如 : 


測試 1-2 : 在 st.container 容器中加入元件的方法 (2) [看原始碼]   

# st-container-test-1-2.py
import streamlit as st

st.subheader('st.container() 容器元件測試')
st.write('這在容器外')
with st.container():
    st.write('這在容器內')
    st.button('這在容器內')
    st.info('這在容器內', icon='ℹ️')
st.write('這在容器外')
st.info('這在容器外', icon='ℹ️')

此例的寫法因為容器物件後面用不到就直接寫在 with 裡. 在 with 區塊內呼叫 st.xxx() 建立的元件都在容器內, 在 with 區塊外呼叫的 st.xxx() 都在容器外, 結果與上面相同. 


2. 動態容器 st.empty() : 

呼叫 st.empty() 函式會建立一個不可見, 且可被動態覆寫的動態容器, 它沒有傳入參數, 傳回值是一個容器類別 DeltaGenerator 的物件 (但只能放一個元件), 幾乎所有 st.xxx() 函式的名稱都可以作為此容器物件的方法名稱來呼叫以便在容器內建立 UI 元件 : 

placeholder=st.empty()
placeholder.xxx()   # 在動態容器中加入 st.xxx() 元件
placeholder.yyy()   # 在動態容器中加入 st.yyy() 元件

但 st.empty() 傳回的容器物件比較特別, 它一次只能放置一個 UI 元件, 加入第二個會把前一個覆蓋掉, 所以上面程式執行後只會顯示最後一個元件 st.yyy() 而已. 

如果要在 st.empty() 容器內放進多個 UI 元件須呼叫其 container() 方法, 它也會傳回一個 DeltaGenerator 物件, 這與 st.container() 傳回的 DeltaGenerator 物件類似, 可以放入多個 UI 元件 (不會被覆蓋), 用法與上面 st.container() 一樣 :

container=placeholder.container()
container.xxx()   # 加入 st.xxx() 元件
container.yyy()   # 加入 st.yyy() 元件

或者使用 with 語法 : 

with placeholder.container():
    st.xxx()  # 加入 st.xxx() 元件
    st.yyy()  # 加入 st.yyy() 元件

例如 : 


測試 2-1 : 在 st.empty() 容器中加入元件的方法 (1) [看原始碼]   

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

st.subheader('st.empty() 容器元件測試')
st.write('這在容器外')
placeholder=st.empty()
container=placeholder.container()  # 取得可加入多元件之容器 
container.write('這在容器內')
container.button('這在容器內')
container.info('這在容器內', icon='ℹ️')
st.write('這在容器外')
st.info('這在容器外', icon='ℹ️')

結果如下 : 




下面範例改用 with 語法 :  


測試 2-2 : 在 st.empty() 容器中加入元件的方法 (2) [看原始碼]   

# st-empty-test-1-2.py
import streamlit as st

st.subheader('st.empty() 容器元件測試')
st.write('這在容器外')
placeholder=st.empty()
with placeholder.container():
    st.write('這在容器內')
    st.button('這在容器內')
    st.info('這在容器內', icon='ℹ️')
st.write('這在容器外')
st.info('這在容器外', icon='ℹ️')

結果與上面相同. 

st.empty() 元件的動態功能來自於其 empty() 方法, 呼叫此方法會清除容器內容, 如果內容是利用 container() 方法傳回的容器放置的多個 UI 元件, 它們會被 empty() 方法一次清空, 例如 : 


測試 2-3 : 清除 st.empty() 容器內容 [看原始碼]   

# st-empty-test-1-3.py
import streamlit as st

st.subheader('st.empty() 容器元件測試')
placeholder=st.empty()
with placeholder.container():
    st.write('這在容器內')
    st.button('這在容器內')
    st.info('這在容器內', icon='ℹ️')
clear_btn=st.button('清除容器內容')
if clear_btn:
    placeholder.empty()
    st.info('容器內容已清除', icon='ℹ️')

此例在 st.empty() 動態容器內放置了 st.write(), st.button(), 以及 st.info() 三個 UI 元件, 另外在容器外則放置了一個清除容器內容的按鈕, 執行後結果如下 : 




按下 '清除容器內容' 按鈕時容器內的三個元件全部被清空, 因為它們在 placeholder 容器看來其實是捆在一起的單一元件 :




下面範例使用 time.sleep() 來模擬 st.empty() 內容的時間變化 :


測試 2-4 : 模擬 st.empty() 內容的時間變化 [看原始碼]   

# st-empty-test-1-4.py
import streamlit as st
import time

st.subheader('st.empty() 容器元件測試')
placeholder=st.empty()
with placeholder.container():
    st.info('正在處理中 ...', icon='ℹ️')
    time.sleep(5)
placeholder.empty()
st.info('處理完成!', icon='ℹ️')

此例會先在容器中顯示 '正在處理中 ...' 提示, 5 秒後清除容器內容, 結果如下 : 




可以串接多個 time.sleep() 使容器內容按時間軸動態變化. 

沒有留言 :