Define multipage apps with st.Page and st.navigation

st.Pagest.navigation 是定义多页面应用的首选命令。使用这些命令,您可以灵活地组织项目文件并自定义导航菜单。只需使用 st.Page 初始化 StreamlitPage 对象,然后在入口文件(即传递给 streamlit run 的文件)中将这些 StreamlitPage 对象传递给 st.navigation

本页面假设您理解概述中介绍的页面术语

当使用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()

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()

如果你想将页面分组,st.navigation 允许你在导航中插入标题。或者,你可以禁用默认的导航小部件,并使用 st.page_link 构建自定义导航菜单。

此外,您可以动态更改传递给st.navigation的页面。然而,只有st.navigation返回的页面接受.run()方法。如果用户输入带有路径名的URL,并且该路径名未与st.navigation中的页面关联(在首次运行时),Streamlit将抛出“页面未找到”错误并将用户重定向到默认页面。

只要您不想在导航菜单中隐藏一个有效且可访问的页面,自定义导航菜单的最简单方法就是在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()

您可以通过更新st.navigation中的页面列表来更改用户可访问的页面。这是一种处理基于角色或用户的页面访问权限的便捷方式。有关更多信息,请查看我们的教程创建动态导航菜单

如果您想对导航菜单有更多的控制,您可以隐藏默认导航并构建自己的导航。您可以通过在st.navigation命令中包含position="hidden"来隐藏默认导航。如果您希望某个页面对用户可用但不显示在导航菜单中,您必须使用此方法。如果页面未包含在st.navigation中,用户将无法被路由到该页面。这适用于通过URL导航以及像st.switch_pagest.page_link这样的命令。

forum

还有问题吗?

我们的 论坛 充满了有用的信息和Streamlit专家。