Streamlit(二十三)- 教程(二)- 动态导航

文章目录

  • [动态导航菜单(st.navigation / st.Page)](#动态导航菜单(st.navigation / st.Page))
    • [1.1 功能概述](#1.1 功能概述)
      • [1.1.1 组件简介](#1.1.1 组件简介)
      • [1.1.2 核心应用场景](#1.1.2 核心应用场景)
      • [1.1.3 版本前置要求](#1.1.3 版本前置要求)
    • [1.2 核心两个API介绍](#1.2 核心两个API介绍)
      • [1.2.1 st.Page:页面封装对象](#1.2.1 st.Page:页面封装对象)
        • [1.2.1.1 两种创建方式](#1.2.1.1 两种创建方式)
        • [1.2.1.2 关键参数](#1.2.1.2 关键参数)
      • [1.2.2 st.navigation:导航菜单生成器](#1.2.2 st.navigation:导航菜单生成器)
        • [1.2.2.1 入参格式](#1.2.2.1 入参格式)
    • [1.3 完整权限动态导航开发流程(教程示例)](#1.3 完整权限动态导航开发流程(教程示例))
      • [1.3.1 步骤1:初始化项目目录与页面文件](#1.3.1 步骤1:初始化项目目录与页面文件)
      • [1.3.2 步骤2:会话状态全局初始化](#1.3.2 步骤2:会话状态全局初始化)
      • [1.3.3 步骤3:定义函数式登录/登出页面](#1.3.3 步骤3:定义函数式登录/登出页面)
      • [1.3.4 步骤4:批量创建所有Page页面对象](#1.3.4 步骤4:批量创建所有Page页面对象)
      • [1.3.5 步骤5:根据角色动态组装页面分组字典](#1.3.5 步骤5:根据角色动态组装页面分组字典)
      • [1.3.6 步骤6:渲染导航并执行页面](#1.3.6 步骤6:渲染导航并执行页面)
    • [1.4 核心特性总结](#1.4 核心特性总结)
    • [1.5 完整示例代码](#1.5 完整示例代码)

动态导航菜单(st.navigation / st.Page)

1.1 功能概述

1.1.1 组件简介

st.navigationst.Page 是 Streamlit 1.36.0 新增的多页面应用API,用于动态生成侧边栏导航菜单

每次页面重运行时可更新页面列表,实现基于用户角色、权限的动态菜单渲染,适配权限管控、按需展示菜单等业务场景。

1.1.2 核心应用场景

  1. 搭建权限系统:不同角色(访客/普通用户/管理员)看到不同导航页面;
  2. 动态加载菜单:根据业务数据、登录状态增减导航条目;
  3. 自定义多页面分组:对页面进行分类分组,侧边栏生成菜单分区标题。

1.1.3 版本前置要求

python 复制代码
# Streamlit 最低版本限制
streamlit >= 1.36.0

1.2 核心两个API介绍

1.2.1 st.Page:页面封装对象

用于封装单个页面,支持本地py文件页面、函数式页面两种定义方式,可配置标题、图标、是否设为默认首页。

1.2.1.1 两种创建方式
  1. 文件页面(项目py文件)
python 复制代码
# 参数:文件路径、菜单标题、侧边栏图标、是否默认首页
settings_page = st.Page(
    "settings.py",
    title="账号设置",
    icon=":material/settings:",
    default=False
)
  1. 函数页面(当前脚本内定义函数,如登录、登出页)
python 复制代码
def login():
    st.header("用户登录")
    role = st.selectbox("选择角色", [None, "Requester", "Responder", "Admin"])
    if st.button("登录"):
        st.session_state.role = role
        st.rerun()

# 封装登录函数为页面
login_page = st.Page(login, title="登录页")
1.2.1.2 关键参数
  • title:侧边栏菜单显示名称;
  • icon:Material图标标识,美化侧边栏;
  • default:布尔值,当前用户进入应用时默认打开该页面。

1.2.2 st.navigation:导航菜单生成器

接收分组页面字典 ,自动渲染侧边栏分组导航菜单,返回导航实例,调用 .run() 执行当前选中页面。

1.2.2.1 入参格式

字典结构:{"分组标题": [页面对象列表]},字典的键对应侧边栏菜单分区标题,值为该分组下所有st.Page对象。

python 复制代码
# 页面分组字典示例
page_groups = {
    "账号管理": [logout_page, settings_page],
    "需求模块": [request_1, request_2]
}
# 生成导航菜单
nav = st.navigation(page_groups)
# 运行当前选中页面
nav.run()

1.3 完整权限动态导航开发流程(教程示例)

1.3.1 步骤1:初始化项目目录与页面文件

  1. 项目入口文件:streamlit_app.py(程序启动文件);
  2. 独立页面文件:settings.py、分角色文件夹admin/request/respond/存放角色专属页面;
  3. 静态资源文件夹:images/存放logo图片。

1.3.2 步骤2:会话状态全局初始化

在入口文件初始化登录角色,用于权限判断:

python 复制代码
# 初始化角色会话状态,None=未登录访客
if "role" not in st.session_state:
    st.session_state.role = None
# 定义全部可用角色
ROLES = [None, "Requester", "Responder", "Admin"]

1.3.3 步骤3:定义函数式登录/登出页面

python 复制代码
# 登录页面函数
def login():
    st.header("登录")
    selected_role = st.selectbox("选择你的角色", ROLES)
    if st.button("确认登录"):
        st.session_state.role = selected_role
        st.rerun()

# 登出页面函数
def logout():
    # 清空角色并重跑,直接跳转登录页
    st.session_state.role = None
    st.rerun()

1.3.4 步骤4:批量创建所有Page页面对象

  1. 账号通用页面(所有登录用户可见)
python 复制代码
logout_page = st.Page(logout, title="退出登录", icon=":material/logout:")
settings_page = st.Page("settings.py", title="账号设置", icon=":material/settings:")
account_pages = [logout_page, settings_page]
  1. 分角色业务页面
python 复制代码
# 需求方页面
request_1 = st.Page("request/request_1.py", title="需求提交1", default=(st.session_state.role == "Requester"))
request_pages = [request_1, ...]

# 响应方页面
respond_pages = [...]
# 管理员页面
admin_pages = [...]

1.3.5 步骤5:根据角色动态组装页面分组字典

根据st.session_state.role的值,动态筛选该角色允许访问的页面,组装分组字典:

python 复制代码
page_dict = {}
current_role = st.session_state.role

# 按角色填充对应业务页面分组
if current_role in ["Requester", "Admin"]:
    page_dict["需求管理"] = request_pages
if current_role in ["Responder", "Admin"]:
    page_dict["处理响应"] = respond_pages
if current_role == "Admin":
    page_dict["管理员后台"] = admin_pages

# 所有登录用户都展示账号分组页面
if len(page_dict) > 0:
    page_dict = {"账号中心": account_pages} | page_dict

1.3.6 步骤6:渲染导航并执行页面

区分未登录访客已登录用户两种逻辑:

python 复制代码
# 全局通用顶部Logo(所有页面共享)
st.logo("images/horizontal_blue.png", icon_image="images/icon_blue.png")
st.title("需求管理系统")

# 未登录:仅展示登录页面
if not page_dict:
    nav = st.navigation([st.Page(login)])
# 已登录:渲染动态分组菜单
else:
    nav = st.navigation(page_dict)

# 执行当前选中的页面
nav.run()

1.4 核心特性总结

  1. 权限动态渲染:基于会话状态、用户角色实时筛选菜单,实现细粒度权限控制;
  2. 菜单分组管理:通过字典键实现侧边栏菜单分区,页面分类清晰;
  3. 双类型页面支持:同时支持外部文件页面、脚本内函数页面(登录/弹窗页);
  4. 全局共享元素 :入口文件中定义的st.logo()st.title()会在所有页面顶部统一展示;
  5. 默认首页配置 :通过default参数为不同角色设置专属默认打开页面;
  6. 轻量化多页面 :替代传统pages/文件夹静态多页面,菜单完全代码可控,无需固定目录结构。

1.5 完整示例代码

python 复制代码
import streamlit as st

# 初始化角色会话状态,None=未登录访客
if "role" not in st.session_state:
    st.session_state.role = None
# 定义全部可用角色
ROLES = [None, "Requester", "Responder", "Admin"]


# 登录页面函数
def login():
    st.header("登录")
    selected_role = st.selectbox("选择你的角色", ROLES)
    if st.button("确认登录"):
        st.session_state.role = selected_role
        st.rerun()


# 登出页面函数
def logout():
    # 清空角色并重跑,直接跳转登录页
    st.session_state.role = None
    st.rerun()


logout_page = st.Page(logout, title="退出登录", icon=":material/logout:")
settings_page = st.Page("settings.py", title="账号设置", icon=":material/settings:")
account_pages = [logout_page, settings_page]
# 需求方页面
request_1 = st.Page("request/request_1.py", title="需求提交1", default=(st.session_state.role == "Requester"))
request_pages = [request_1, ...]

# 响应方页面
respond_pages = [...]
# 管理员页面
admin_pages = [...]
page_dict = {}
current_role = st.session_state.role

# 按角色填充对应业务页面分组
if current_role in ["Requester", "Admin"]:
    page_dict["需求管理"] = request_pages
if current_role in ["Responder", "Admin"]:
    page_dict["处理响应"] = respond_pages
if current_role == "Admin":
    page_dict["管理员后台"] = admin_pages

# 所有登录用户都展示账号分组页面
if len(page_dict) > 0:
    page_dict = {"账号中心": account_pages} | page_dict
# 全局通用顶部Logo(所有页面共享)
st.logo("images/horizontal_blue.png", icon_image="images/icon_blue.png")
st.title("需求管理系统")

# 未登录:仅展示登录页面
if not page_dict:
    nav = st.navigation([st.Page(login)])
# 已登录:渲染动态分组菜单
else:
    nav = st.navigation(page_dict)

# 执行当前选中的页面
nav.run()
相关推荐
心中有国也有家3 小时前
GE图引擎深度解析——CANN的计算图优化与执行引擎
人工智能·pytorch·python·学习·numpy
卷毛的技术笔记5 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥5 小时前
匿名函数 lambda + 高阶函数
java·python·算法
vb2008115 小时前
FastAPI APIRouter
开发语言·python
adrninistrat0r5 小时前
Java调用链MCP分析工具
java·python·ai编程
杨充5 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
meilindehuzi_a6 小时前
深入浅出数据结构:Python 字典(Dict)与集合(Set)的哈希表底层全链路追踪
数据结构·python·散列表
Lucas凉皮6 小时前
20243408 2025-2026-2 《Python程序设计》综合实践报告
python·实验报告
键盘上的猫头鹰6 小时前
【MySQL 教程(八)】索引、事务、用户管理、导入导出与分页查询
数据库·python·mysql