如何在Streamlit页面更新后保留AgGrid选中行?
问题:Streamlit AgGrid自动刷新后丢失选中行
开发实时指标仪表盘时,使用AgGrid展示数据,通过st_autorefresh实现每15秒自动加载数据。但每次页面刷新后,即便配置了pre_selected_rows,AgGrid仍会丢失之前选中的行。
解决方法
问题根源在于依赖前端渲染后的临时行索引(nodeRowIndex)保存选中状态,但刷新后数据排序(代码中设置了sort='desc')会导致索引对应关系失效,且nodeRowIndex不是数据本身的稳定标识。
正确做法是基于数据的唯一主键(比如你的ID列)跟踪选中状态:
- 保存选中行的唯一ID到
session_state,而非临时行索引 - 刷新时根据唯一ID匹配数据行,生成
pre_selected_rows - 调整
GridUpdateMode为更适配的模式,避免不必要的状态重置
修改后的代码
import numpy as np import pandas as pd import streamlit as st from streamlit_autorefresh import st_autorefresh from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, DataReturnMode # 初始化session_state,保存选中行的ID if 'selected_ids' not in st.session_state: st.session_state.selected_ids = [] # 生成模拟数据 df = pd.DataFrame({ 'ID': [1, 2, 3], 'STATUS': np.random.randint(0,100,size=(3)) }) st.write(df) # 根据保存的ID匹配当前数据中的行,生成pre_selected_rows pre_selected_rows = df[df['ID'].isin(st.session_state.selected_ids)].to_dict('records') st.write("已选中的ID: ", st.session_state.selected_ids) # 构建Grid选项 gb = GridOptionsBuilder.from_dataframe(df) gb.configure_default_column(editable=True, wrapText=True, autoHeight=True) gb.configure_column( 'ID', minWidth=80, maxWidth=80, type=["numericColumn","numberColumnFilter"], sortable=True, sort='desc', checkboxSelection=True, headerCheckboxSelection=True ) gb.configure_column('STATUS', minWidth=100, maxWidth=100) gb.configure_pagination(paginationAutoPageSize=False, paginationPageSize=3) gb.configure_side_bar() gb.configure_selection('multiple', pre_selected_rows=pre_selected_rows, use_checkbox=True) gb_grid_options = gb.build() # 渲染AgGrid grid_return = AgGrid( df, gridOptions=gb_grid_options, key='ag_grid', # 使用固定key,避免每次刷新重建组件 reload_data=True, data_return_mode=DataReturnMode.AS_INPUT, update_mode=GridUpdateMode.SELECTION_CHANGED, # 仅在选中变化时更新 allow_unsafe_jscode=True, fit_columns_on_grid_load=False, enable_enterprise_modules=False, height=320, width='100%', theme="streamlit" ) # 更新session_state中的选中ID selected_rows = grid_return["selected_rows"] st.session_state.selected_ids = [row['ID'] for row in selected_rows] st.write("选中行: ", selected_rows) # 自动刷新 st_autorefresh(interval=15*1000, key="dataframerefresh")
关键改动说明
- 用
selected_ids存储选中行的唯一ID,替代临时行索引,确保刷新后能准确匹配数据 - 生成
pre_selected_rows时,通过ID筛选当前数据中的对应行,而非依赖不稳定的前端索引 - 将
GridUpdateMode改为SELECTION_CHANGED,减少不必要的状态更新触发 - 给AgGrid设置固定的
key='ag_grid',避免组件每次刷新被完全重建导致状态丢失
内容的提问来源于stack exchange,提问作者Andrews Cordolino Sobral
相关产品推荐
相关产品推荐

