Working with widgets in multipage apps
当你在Streamlit应用中创建一个小部件时,Streamlit会生成一个小部件ID,并使用它来使你的小部件具有状态。随着应用因用户交互而重新运行,Streamlit通过将小部件的值与其ID关联来跟踪小部件的值。特别是,小部件的ID取决于它被创建的页面。如果你在两个不同的页面上定义了相同的小部件,那么当你切换页面时,小部件将重置为其默认值。
本指南解释了三种策略,如果您希望小部件在所有页面上保持状态,可以使用这些策略。如果您不希望小部件出现在所有页面上,但希望在离开其页面(然后返回)时保持状态,可以使用选项2和3。有关这些策略的详细信息,请参阅Understanding widget behavior。
Option 1 (preferred): Execute your widget command in your entrypoint file
当你使用st.Page和st.navigation定义你的多页面应用时,你的入口文件将成为页面周围的公共元素的框架。当你在入口文件中执行一个小部件命令时,Streamlit 将该小部件与你的入口文件关联,而不是与特定页面关联。由于你的入口文件在每次应用重新运行时都会执行,因此当用户在页面之间切换时,入口文件中的任何小部件都将保持状态。
如果您使用pages/目录定义您的应用程序,则此方法无效。
以下示例在侧边栏中包含一个选择框和滑块,这些组件在所有页面上都是渲染的并且有状态的。每个小部件都有一个分配的键,因此您可以通过页面内的会话状态访问它们的值。
目录结构:
your-repository/
├── page_1.py
├── page_2.py
└── streamlit_app.py
streamlit_app.py:
import streamlit as st
pg = st.navigation([st.Page("page_1.py"), st.Page("page_2.py")])
st.sidebar.selectbox("Group", ["A","B","C"], key="group")
st.sidebar.slider("Size", 1, 5, key="size")
pg.run()
Option 2: Save your widget values into a dummy key in Session State
如果你想从一个部件导航离开并返回到它,同时保持它的值,或者如果你想在多个页面上使用相同的部件,请在st.session_state中使用一个单独的键来独立于部件保存值。在这个例子中,一个临时键与一个部件一起使用。临时键使用下划线前缀。因此,"_my_key"被用作部件键,但数据被复制到"my_key"以在页面之间保留它。
import streamlit as st
def store_value():
# Copy the value to the permanent key
st.session_state["my_key"] = st.session_state["_my_key"]
# Copy the saved value to the temporary key
st.session_state["_my_key"] = st.session_state["my_key"]
st.number_input("Number of filters", key="_my_key", on_change=store_value)
如果将其功能化以与多个小部件一起使用,它可能看起来像这样:
import streamlit as st
def store_value(key):
st.session_state[key] = st.session_state["_"+key]
def load_value(key):
st.session_state["_"+key] = st.session_state[key]
load_value("my_key")
st.number_input("Number of filters", key="_my_key", on_change=store_value, args=["my_key"])
Option 3: Interrupt the widget clean-up process
当Streamlit运行到应用程序的末尾时,它将删除未渲染的任何小部件的数据。这包括与当前页面无关的任何小部件的数据。然而,如果你在应用程序运行中重新保存一个键值对,Streamlit将不会将该键值对与任何小部件关联,直到你再次使用该键执行小部件命令。
因此,如果您在每个页面的顶部都有以下代码,任何带有键"my_key"的小部件无论在哪里渲染(或不渲染)都将保留其值。或者,如果您正在使用st.navigation和st.Page,您可以在执行页面之前在入口点文件中包含此代码一次。
if "my_key" in st.session_state:
st.session_state.my_key = st.session_state.my_key
还有问题吗?
我们的 论坛 充满了有用的信息和Streamlit专家。