You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit应用遇DuplicateWidgetID错误:st.checkbox重复Key问题求助

修复Streamlit的DuplicateWidgetID错误:重复Checkbox Key问题

问题场景

开发Streamlit应用时,在tab2直接调用func(),tab3通过chart()间接调用func(),触发DuplicateWidgetID错误,提示存在多个内部Key相同的st.checkbox组件。

错误原因

func()函数内部直接创建了侧边栏的checkbox组件,每次调用func()都会重新渲染这些组件。由于tab2和tab3同时触发func()调用,同一渲染周期内生成了两组结构完全一致的checkbox,Streamlit自动生成的内部Key重复,导致组件冲突。

修复方案

方案1:为Checkbox指定唯一Key

直接给每个st.checkbox添加唯一的key参数,确保组件标识不重复:

def func():
    # 为每个checkbox设置唯一key
    option_1 = st.sidebar.checkbox('x1', value=True, key='cb_x1')
    option_2 = st.sidebar.checkbox('x2', key='cb_x2')
    option_3 = st.sidebar.checkbox('x3', key='cb_x3')

    dfall = read()
    dfs = []
    if option_1 :
        dfs.append(dfall[0])
    if option_2 :
        dfs.append(dfall[1])
    if option_3 :
        dfs.append(dfall[2])

    if len(dfs) > 1:
        df = pd.concat(dfs)
    elif len(dfs) == 1:
        df = dfs[0]
    else:
        # 处理未选中任何选项的边界情况
        df = pd.DataFrame()

    # 后续数据处理逻辑
    # do something on df..
    return df

def chart():
   df= func()
   # 图表绘制逻辑
   # plot the chart 
   return 

with tab1:
    intro()

with tab2:
    func()
    
with tab3:
    chart()

方案2:分离控件与数据处理(更推荐)

将侧边栏控件的创建逻辑单独抽离,func()仅负责数据处理,避免重复创建组件:

# 单独创建侧边栏控件,仅执行一次
def create_sidebar_widgets():
    option_1 = st.sidebar.checkbox('x1', value=True, key='cb_x1')
    option_2 = st.sidebar.checkbox('x2', key='cb_x2')
    option_3 = st.sidebar.checkbox('x3', key='cb_x3')
    return option_1, option_2, option_3

# 数据处理函数,依赖外部传入的控件状态
def func(option_1, option_2, option_3):
    dfall = read()
    dfs = []
    if option_1 :
        dfs.append(dfall[0])
    if option_2 :
        dfs.append(dfall[1])
    if option_3 :
        dfs.append(dfall[2])

    if len(dfs) > 1:
        df = pd.concat(dfs)
    elif len(dfs) == 1:
        df = dfs[0]
    else:
        df = pd.DataFrame()

    # do something on df..
    return df

def chart(option_1, option_2, option_3):
   df= func(option_1, option_2, option_3)
   # plot the chart 
   return 

# 主流程
opt1, opt2, opt3 = create_sidebar_widgets()

with tab1:
    intro()

with tab2:
    func(opt1, opt2, opt3)
    
with tab3:
    chart(opt1, opt2, opt3)

方案2的优势在于侧边栏控件仅初始化一次,所有标签页共享同一组控件状态,既避免了重复创建组件的问题,也让代码职责更清晰。

内容的提问来源于stack exchange,提问作者user14269252

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 20:33:23