st.Page
and st.navigation
Define multipage apps with
st.Page
和 st.navigation
是定义多页面应用的首选命令。使用这些命令,您可以灵活地组织项目文件并自定义导航菜单。只需使用 st.Page
初始化 StreamlitPage
对象,然后在入口文件(即传递给 streamlit run
的文件)中将这些 StreamlitPage
对象传递给 st.navigation
。
本页面假设您理解概述中介绍的页面术语。
App structure
当使用st.navigation
时,你的入口文件就像一个页面路由器。每个页面都是从你的入口文件执行的脚本。你可以从Python文件或函数中定义一个页面。如果你在入口文件中包含元素或小部件,它们将成为页面之间的公共元素。在这种情况下,你可以将你的入口文件想象成每个页面的画框。
你只能在每次应用运行时调用一次st.navigation
,并且必须从入口点文件中调用它。当用户在导航中选择一个页面(或通过类似st.switch_page
的命令进行路由)时,st.navigation
会返回选定的页面。你必须使用.run()
方法手动执行该页面。以下示例是一个两页应用,其中每个页面都由一个Python文件定义。
目录结构:
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")])
pg.run()
Defining pages
st.Page
允许您定义一个页面。第一个也是唯一一个必需的参数定义了您的页面源,它可以是一个Python文件或函数。当使用Python文件时,您的页面可能位于子目录(或上级目录)中。页面文件的路径必须始终相对于入口点文件。一旦您创建了页面对象,将它们传递给st.navigation
以将它们注册为应用程序中的页面。
如果您没有定义页面标题或URL路径名,Streamlit将从文件或函数名称中推断它们,如多页面应用程序概述中所述。然而,st.Page
允许您手动配置它们。在st.Page
中,Streamlit使用title
来设置页面标签和标题。此外,Streamlit使用icon
来设置页面图标和网站图标。如果您希望有不同的页面标题和标签,或不同的页面图标和网站图标,您可以使用st.set_page_config
来更改页面标题和/或网站图标。只需在st.navigation
之后调用st.set_page_config
,无论是在您的入口点文件中还是在您的页面源代码中。
以下示例使用st.set_page_config
来在所有页面上一致地设置页面标题和图标。每个页面在导航菜单中都有自己的标签和图标,但浏览器标签将在所有页面上显示一致的标题和图标。
目录结构:
your-repository/
├── create.py
├── delete.py
└── streamlit_app.py
streamlit_app.py
:
import streamlit as st
create_page = st.Page("create.py", title="Create entry", icon=":material/add_circle:")
delete_page = st.Page("delete.py", title="Delete entry", icon=":material/delete:")
pg = st.navigation([create_page, delete_page])
st.set_page_config(page_title="Data manager", page_icon=":material/edit:")
pg.run()

Customizing navigation
如果你想将页面分组,st.navigation
允许你在导航中插入标题。或者,你可以禁用默认的导航小部件,并使用 st.page_link
构建自定义导航菜单。
此外,您可以动态更改传递给st.navigation
的页面。然而,只有st.navigation
返回的页面接受.run()
方法。如果用户输入带有路径名的URL,并且该路径名未与st.navigation
中的页面关联(在首次运行时),Streamlit将抛出“页面未找到”错误并将用户重定向到默认页面。
Adding section headers
只要您不想在导航菜单中隐藏一个有效且可访问的页面,自定义导航菜单的最简单方法就是在st.navigation
内组织页面。您可以对页面进行排序或分组,以及删除任何您不希望用户访问的页面。这是处理用户权限的一种便捷方式。
以下示例创建了两个菜单状态。当用户开始新会话时,他们未登录。在这种情况下,唯一可用的页面是登录页面。如果用户尝试通过URL访问其他页面,它将创建一个新会话,Streamlit将无法识别该页面。用户将被重定向到登录页面。然而,用户登录后,他们将看到一个包含三个部分的导航菜单,并被引导到仪表板作为应用程序的默认页面(即主页)。
目录结构:
your-repository/
├── reports
│ ├── alerts.py
│ ├── bugs.py
│ └── dashboard.py
├── tools
│ ├── history.py
│ └── search.py
└── streamlit_app.py
streamlit_app.py
:
import streamlit as st
if "logged_in" not in st.session_state:
st.session_state.logged_in = False
def login():
if st.button("Log in"):
st.session_state.logged_in = True
st.rerun()
def logout():
if st.button("Log out"):
st.session_state.logged_in = False
st.rerun()
login_page = st.Page(login, title="Log in", icon=":material/login:")
logout_page = st.Page(logout, title="Log out", icon=":material/logout:")
dashboard = st.Page(
"reports/dashboard.py", title="Dashboard", icon=":material/dashboard:", default=True
)
bugs = st.Page("reports/bugs.py", title="Bug reports", icon=":material/bug_report:")
alerts = st.Page(
"reports/alerts.py", title="System alerts", icon=":material/notification_important:"
)
search = st.Page("tools/search.py", title="Search", icon=":material/search:")
history = st.Page("tools/history.py", title="History", icon=":material/history:")
if st.session_state.logged_in:
pg = st.navigation(
{
"Account": [logout_page],
"Reports": [dashboard, bugs, alerts],
"Tools": [search, history],
}
)
else:
pg = st.navigation([login_page])
pg.run()

Dynamically changing the available pages
您可以通过更新st.navigation
中的页面列表来更改用户可访问的页面。这是一种处理基于角色或用户的页面访问权限的便捷方式。有关更多信息,请查看我们的教程创建动态导航菜单。
Building a custom navigation menu
如果您想对导航菜单有更多的控制,您可以隐藏默认导航并构建自己的导航。您可以通过在st.navigation
命令中包含position="hidden"
来隐藏默认导航。如果您希望某个页面对用户可用但不显示在导航菜单中,您必须使用此方法。如果页面未包含在st.navigation
中,用户将无法被路由到该页面。这适用于通过URL导航以及像st.switch_page
和st.page_link
这样的命令。
还有问题吗?
我们的 论坛 充满了有用的信息和Streamlit专家。