Skip to content

Streamlit 核心组件 ​

1. 文本组件 ​

1.1 标题与文本 ​

python
import streamlit as st

# 标题
st.title("主标题")
st.header("一级标题")
st.subheader("二级标题")

# 普通文本
st.text("等宽字体文本,不会自动换行")

# Markdown 支持
st.markdown("**粗体** *斜体* `代码`")
st.markdown("## Markdown 标题")
st.markdown("- 列表项1\n- 列表项2\n- 列表项3")

# 带颜色的 Markdown
st.markdown(":red[红色文字] :blue[蓝色文字] :green[绿色文字]")

# LaTeX 公式
st.latex(r"E = mc^2")
st.latex(r"\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}")

# 代码块
st.code("""
def hello():
    print("Hello, Streamlit!")
""", language="python")

# 行内代码
st.markdown("使用 `pip install streamlit` 安装")

# 引用
st.markdown("> 这是一段引用文字")

# 分割线
st.divider()

# 注释
st.caption("这是一段小字说明")

1.2 状态提示 ​

python
import streamlit as st
import time

# 信息提示
st.info("这是一条信息提示")
st.success("操作成功!")
st.warning("注意:这是一个警告")
st.error("出错了!请检查输入")

# 特殊文本
st.title("标题", anchor="my-anchor")  # 带锚点
st.write("自动判断类型并渲染")
st.write(123)          # 数字
st.write([1, 2, 3])    # 列表
st.write({"a": 1})     # 字典
st.write(pd.DataFrame()) # DataFrame

# 使用 empty 占位符动态更新
placeholder = st.empty()
with placeholder.container():
    st.write("正在加载...")
    time.sleep(2)
    st.write("加载完成!")

# 可以清空
# placeholder.empty()

2. 输入组件 ​

2.1 文本输入 ​

python
import streamlit as st

# 单行文本输入
name = st.text_input("姓名", placeholder="请输入你的名字")

# 多行文本输入
bio = st.text_area("个人简介", height=150, placeholder="介绍一下你自己...")

# 密码输入(隐藏输入内容)
password = st.text_input("密码", type="password")

# 带最大长度限制
limited = st.text_input("限长输入", max_chars=50)

# 带默认值
default_text = st.text_input("默认值", value="这是默认文本")

# 带标签帮助
help_text = st.text_input(
    "邮箱",
    help="请输入有效的邮箱地址",
    placeholder="example@mail.com"
)

2.2 数字输入 ​

python
import streamlit as st

# 基本数字输入
age = st.number_input("年龄", min_value=0, max_value=150, value=25)

# 浮点数
price = st.number_input("价格", min_value=0.0, max_value=1000.0,
                         value=9.99, step=0.01, format="%.2f")

# 步进值
count = st.number_input("数量", value=10, step=5)

# 带标签和帮助
score = st.number_input(
    "评分",
    min_value=0,
    max_value=100,
    value=60,
    help="请输入0-100之间的分数"
)

2.3 滑块 ​

python
import streamlit as st

# 基本滑块
age = st.slider("年龄", min_value=0, max_value=100, value=25)

# 带步进
score = st.slider("分数", 0, 100, 50, step=5)

# 浮点数滑块
temperature = st.slider("温度", 0.0, 40.0, 22.5, step=0.5)

# 范围选择
date_range = st.slider(
    "选择日期范围",
    value=(0, 100),
    help="选择一个范围"
)

# 带格式显示
weight = st.slider(
    "体重 (kg)",
    min_value=30.0,
    max_value=150.0,
    value=70.0,
    step=0.5,
    format="%.1f kg"
)

# 时间滑块
import datetime
time_val = st.slider(
    "选择时间",
    value=datetime.time(12, 0),
    format="HH:mm"
)

2.4 选择类组件 ​

python
import streamlit as st

# 下拉选择框
option = st.selectbox(
    "选择颜色",
    ["红色", "蓝色", "绿色", "黄色"],
    index=0  # 默认选中项
)

# 带索引的下拉
color = st.selectbox("颜色", ["红", "绿", "蓝"], index=1)

# 多选下拉
languages = st.multiselect(
    "选择编程语言",
    ["Python", "JavaScript", "Go", "Rust", "Java", "C++"],
    default=["Python"]
)

# 单选按钮
genre = st.radio(
    "选择音乐类型",
    ["流行", "摇滚", "爵士", "古典"],
    horizontal=True  # 水平排列
)

# 复选框
agree = st.checkbox("我同意服务条款")
enable_feature = st.checkbox("启用高级功能", value=True)

# 动态显示内容
if agree:
    st.success("感谢同意!")

if enable_feature:
    st.info("高级功能已启用")

2.5 按钮与文件上传 ​

python
import streamlit as st

# 普通按钮
if st.button("点击我"):
    st.balloons()
    st.toast("🎉 按钮被点击了!")

# 带类型的按钮
st.button("主要按钮", type="primary")
st.button("次要按钮", type="secondary")

# 带图标的按钮
st.button("🚀 发送", type="primary")
st.button("🔄 刷新")

# 文件上传
uploaded_file = st.file_uploader(
    "上传文件",
    type=["csv", "xlsx", "json", "txt", "png", "jpg"],
    accept_multiple_files=True,
    help="支持 CSV, Excel, JSON, TXT, 图片"
)

if uploaded_file:
    if isinstance(uploaded_file, list):
        for f in uploaded_file:
            st.write(f"文件名: {f.name}, 大小: {f.size} bytes")
    else:
        st.write(f"文件名: {uploaded_file.name}")
        st.write(f"文件类型: {uploaded_file.type}")
        st.write(f"文件大小: {uploaded_file.size} bytes")

# 下载按钮
st.download_button(
    label="📥 下载报告",
    data="这是报告内容",
    file_name="report.txt",
    mime="text/plain"
)

# 下载按钮(下载 DataFrame)
import pandas as pd
import io

df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
csv_buffer = io.StringIO()
df.to_csv(csv_buffer, index=False)

st.download_button(
    label="📥 下载CSV",
    data=csv_buffer.getvalue(),
    file_name="data.csv",
    mime="text/csv"
)

3. 数据展示组件 ​

3.1 DataFrame 与 Table ​

python
import streamlit as st
import pandas as pd
import numpy as np

# 创建示例数据
df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五", "赵六", "钱七"],
    "年龄": [25, 30, 35, 28, 42],
    "城市": ["北京", "上海", "广州", "深圳", "杭州"],
    "分数": [85.5, 92.3, 78.9, 95.1, 88.7]
})

# 交互式 DataFrame(支持排序、筛选)
st.dataframe(df, use_container_width=True)

# 静态表格
st.table(df)

# 带列配置的 DataFrame
st.dataframe(
    df,
    column_config={
        "分数": st.column_config.NumberColumn(
            "分数",
            help="满分100",
            format="%.1f",
            min_value=0,
            max_value=100,
        ),
        "年龄": st.column_config.NumberColumn(
            "年龄",
            format="%d 岁",
        ),
    },
    hide_index=True,
    use_container_width=True
)

3.2 Metric 指标卡片 ​

python
import streamlit as st

# 单个指标
st.metric(label="当前用户数", value="1,234", delta="12.5%")

# 带方向的指标
col1, col2, col3 = st.columns(3)

with col1:
    st.metric("总收入", "¥1.2M", delta="5.2%")
with col2:
    st.metric("新用户", "1,023", delta="-3.1%")
with col3:
    st.metric("转化率", "3.2%", delta="0.5%")

# 多行指标
st.metric(
    label="日活跃用户",
    value="2,456",
    delta="123",
    delta_color="inverse"  # 反色(减少显示绿色)
)

# 指标卡片网格
metrics = [
    ("销售量", "1,234", "8.2%"),
    ("访问量", "5,678", "-2.1%"),
    ("转化率", "3.5%", "0.3%"),
    ("客单价", "¥299", "12.5%"),
]

cols = st.columns(4)
for i, (label, value, delta) in enumerate(metrics):
    with cols[i]:
        st.metric(label, value, delta=delta)

3.3 进度条与状态 ​

python
import streamlit as st
import time

# 基本进度条
progress = st.progress(0, text="加载中...")
for i in range(100):
    time.sleep(0.01)
    progress.progress(i + 1, text=f"进度: {i+1}%")
progress.empty()  # 完成后清除

# Spinner(加载动画)
with st.spinner("正在处理数据..."):
    time.sleep(2)
    st.success("处理完成!")

# 状态指示
status = st.status("正在运行...", expanded=True)
status.write("步骤 1: 加载数据")
time.sleep(1)
status.write("步骤 2: 处理数据")
time.sleep(1)
status.write("步骤 3: 生成报告")
time.sleep(1)
status.update(label="完成!", state="complete", expanded=False)

4. 布局组件 ​

4.1 Sidebar 侧边栏 ​

python
import streamlit as st

# 侧边栏标题
st.sidebar.title("导航")

# 侧边栏选择
page = st.sidebar.radio(
    "选择页面",
    ["首页", "数据分析", "设置"]
)

# 侧边栏输入
username = st.sidebar.text_input("用户名")
password = st.sidebar.text_input("密码", type="password")

# 侧边栏按钮
if st.sidebar.button("登录"):
    if username and password:
        st.sidebar.success("登录成功!")
    else:
        st.sidebar.error("请输入用户名和密码")

# 侧边栏分隔线
st.sidebar.divider()

# 侧边栏信息
st.sidebar.markdown("### 关于")
st.sidebar.info("这是一个 Streamlit 示例应用")
st.sidebar.caption("版本 1.0.0")

4.2 Columns 列布局 ​

python
import streamlit as st

# 基本列布局
col1, col2, col3 = st.columns(3)

with col1:
    st.write("第一列")
    st.button("按钮1")

with col2:
    st.write("第二列")
    st.button("按钮2")

with col3:
    st.write("第三列")
    st.button("按钮3")

# 不等宽列
col1, col2, col3 = st.columns([2, 3, 1])  # 比例

with col1:
    st.write("窄列 (2)")

with col2:
    st.write("宽列 (3)")

with col3:
    st.write("最窄列 (1)")

# 嵌套列
outer_col1, outer_col2 = st.columns(2)

with outer_col1:
    st.write("外部左列")
    inner_col1, inner_col2 = st.columns(2)
    with inner_col1:
        st.write("内部左列")
    with inner_col2:
        st.write("内部右列")

with outer_col2:
    st.write("外部右列")

4.3 Tabs 标签页 ​

python
import streamlit as st
import pandas as pd
import numpy as np

# 基本标签页
tab1, tab2, tab3 = st.tabs(["📊 数据", "📈 图表", "⚙️ 设置"])

with tab1:
    st.header("数据视图")
    df = pd.DataFrame(
        np.random.randn(10, 3),
        columns=["A", "B", "C"]
    )
    st.dataframe(df)

with tab2:
    st.header("图表视图")
    st.line_chart(df)

with tab3:
    st.header("设置")
    option = st.selectbox("选择模式", ["标准", "高级"])
    st.write(f"当前模式: {option}")

# 动态标签页
tab_names = ["标签1", "标签2", "标签3"]
tabs = st.tabs(tab_names)

for i, tab in enumerate(tabs):
    with tab:
        st.write(f"这是第 {i+1} 个标签的内容")

4.4 Expander 折叠面板 ​

python
import streamlit as st

# 基本折叠面板
with st.expander("点击展开详情"):
    st.write("这里是详细信息...")
    st.write("更多内容...")

# 默认展开
with st.expander("默认展开", expanded=True):
    st.write("默认就是展开状态")

# 多层嵌套
with st.expander("外层"):
    st.write("外层内容")
    with st.expander("内层"):
        st.write("内层内容")

4.5 Container 容器 ​

python
import streamlit as st

# 容器可以包含任意组件
with st.container():
    st.write("这是容器1的内容")
    st.button("按钮1")

# 带边框的容器(Streamlit 1.28+)
with st.container(border=True):
    st.write("这是带边框的容器")
    st.button("按钮2")

# 高度限制的容器
with st.container(height=300):
    st.write("固定高度的容器")
    for i in range(20):
        st.write(f"第 {i} 行")

4.6 Form 表单 ​

python
import streamlit as st

# 表单:将多个输入组件打包,点击提交按钮后统一处理
with st.form("my_form"):
    st.write("注册表单")
    name = st.text_input("姓名")
    email = st.text_input("邮箱")
    age = st.number_input("年龄", min_value=0, max_value=150)
    gender = st.radio("性别", ["男", "女", "其他"], horizontal=True)
    agree = st.checkbox("同意条款")

    submitted = st.form_submit_button("提交", type="primary")

if submitted:
    if not name or not email:
        st.error("请填写姓名和邮箱!")
    elif not agree:
        st.warning("请同意条款!")
    else:
        st.success(f"注册成功!姓名: {name}, 邮箱: {email}")
        st.write(f"年龄: {age}, 性别: {gender}")

# 带边框的表单
with st.form("form_with_border", clear_on_submit=True):
    st.text_input("搜索关键词")
    submitted = st.form_submit_button("搜索")
    if submitted:
        st.write("搜索中...")

5. 媒体组件 ​

python
import streamlit as st

# 图片
st.image("https://picsum.photos/400/300", caption="随机图片")
st.image("logo.png", width=200)

# 音频
audio_file = open("audio.mp3", "rb")
st.audio(audio_file.read(), format="audio/mp3")

# 或从文件上传
uploaded_audio = st.file_uploader("上传音频", type=["mp3", "wav"])
if uploaded_audio:
    st.audio(uploaded_audio.read(), format=uploaded_audio.type)

# 视频
video_file = open("video.mp4", "rb")
st.video(video_file.read(), format="video/mp4")

6. 图表组件 ​

python
import streamlit as st
import pandas as pd
import numpy as np

# 创建示例数据
chart_data = pd.DataFrame(
    np.random.randn(20, 3),
    columns=["A", "B", "C"]
)

# 内置图表(基于 Altair)
st.line_chart(chart_data["A"])
st.area_chart(chart_data[["A", "B"]])
st.bar_chart(chart_data)

# 散点图
scatter_data = pd.DataFrame({
    "x": np.random.randn(100),
    "y": np.random.randn(100)
})
st.scatter_chart(scatter_data)

# 地图
map_data = pd.DataFrame(
    np.random.randn(100, 2) / [50, 50] + [37.76, -122.4],
    columns=["lat", "lon"]
)
st.map(map_data)

7. 组件速查表 ​

类别组件用途
文本st.title页面大标题
文本st.header一级标题
文本st.subheader二级标题
文本st.markdownMarkdown渲染
文本st.write通用写入
文本st.code代码块
文本st.latexLaTeX公式
输入st.text_input单行文本
输入st.text_area多行文本
输入st.number_input数字输入
输入st.slider滑块
输入st.selectbox下拉选择
输入st.multiselect多选下拉
输入st.radio单选按钮
输入st.checkbox复选框
输入st.button按钮
输入st.file_uploader文件上传
输入st.download_button下载按钮
展示st.dataframe交互式表格
展示st.table静态表格
展示st.metric指标卡片
展示st.progress进度条
展示st.spinner加载动画
展示st.status状态指示
布局st.sidebar侧边栏
布局st.columns列布局
布局st.tabs标签页
布局st.expander折叠面板
布局st.container容器
布局st.form表单
图表st.line_chart折线图
图表st.bar_chart柱状图
图表st.area_chart面积图
图表st.scatter_chart散点图
图表st.map地图
媒体st.image图片
媒体st.audio音频
媒体st.video视频
状态st.success成功提示
状态st.info信息提示
状态st.warning警告提示
状态st.error错误提示
状态st.toast临时通知
其他st.divider分割线
其他st.empty空占位符
其他st.caption小字说明