如何在Streamlit DataFrame中通过列链接更改状态?
解决Streamlit中通过DataFrame列元素更新状态的问题
Streamlit的LinkColumn仅支持URL跳转,无法触发Python端回调或修改session_state,以下是几种可行的替代方案:
方案1:利用Streamlit DataFrame的选中事件(Streamlit 1.28+)
通过监听DataFrame的行选中事件,获取目标Symbol并触发状态更新,无需自定义列元素:
import streamlit as st import pandas as pd def show_company_info(symbol): # 将选中的Symbol存入session_state,用于后续图表更新 st.session_state.selected_symbol = symbol # 示例:生成对应公司的图表 st.line_chart(pd.DataFrame( {"收盘价": [102, 98, 105, 103]}, index=[f"{symbol}_D1", f"{symbol}_D2", f"{symbol}_D3", f"{symbol}_D4"] )) # 初始化状态 if "selected_symbol" not in st.session_state: st.session_state.selected_symbol = None # 构造示例数据 df = pd.DataFrame({ "Symbol": ["CXAI", "AAPL", "MSFT"], "当前价": [100, 150, 300], "涨跌幅": ["+2.1%", "-0.5%", "+1.3%"] }) # 渲染DataFrame并启用单行选中 selected_rows = st.dataframe( df, on_select="rerun", selection_mode="single-row", hide_index=True, use_container_width=True ) # 选中行时触发信息展示 if selected_rows.get("rows"): selected_symbol = df.iloc[selected_rows["rows"][0]]["Symbol"] show_company_info(selected_symbol)
方案2:将列元素替换为可点击按钮
直接把Symbol列改成按钮,点击时触发回调更新状态:
import streamlit as st import pandas as pd def show_company_info(symbol): st.session_state.selected_symbol = symbol # 示例图表 st.bar_chart(pd.DataFrame( {"成交量": [5000, 3000, 7000]}, index=[f"{symbol}_早", f"{symbol}_中", f"{symbol}_晚"] )) if "selected_symbol" not in st.session_state: st.session_state.selected_symbol = None df = pd.DataFrame({ "Symbol": ["CXAI", "AAPL", "MSFT"], "当前价": [100, 150, 300] }) # 将Symbol列替换为按钮 df["查看详情"] = df["Symbol"].apply( lambda x: st.button(x, key=f"btn_{x}", on_click=show_company_info, args=(x,)) ) st.dataframe(df.drop(columns=["Symbol"]), hide_index=True) # 显示当前选中状态 if st.session_state.selected_symbol: st.markdown(f"**当前选中公司**: {st.session_state.selected_symbol}")
方案3:使用AgGrid实现更灵活的单元格交互
如果需要更复杂的DataFrame交互逻辑,可借助st_aggrid组件实现单元格点击回调:
import streamlit as st import pandas as pd from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode def show_company_info(symbol): st.session_state.selected_symbol = symbol st.area_chart(pd.DataFrame( {"市值": [200, 210, 195, 205]}, index=[f"{symbol}_W1", f"{symbol}_W2", f"{symbol}_W3", f"{symbol}_W4"] )) if "selected_symbol" not in st.session_state: st.session_state.selected_symbol = None df = pd.DataFrame({ "Symbol": ["CXAI", "AAPL", "MSFT"], "当前价": [100, 150, 300] }) # 配置AgGrid,给Symbol列添加可点击按钮 gb = GridOptionsBuilder.from_dataframe(df) gb.configure_column( "Symbol", cellRenderer="agButtonCellRenderer", cellRendererParams={ "text": "点击查看", "onClick": "function(e) { e.api.dispatchEvent(new CustomEvent('cellClick', {detail: e.data.Symbol})); }" } ) grid_options = gb.build() # 渲染AgGrid并监听自定义事件 grid_response = AgGrid( df, gridOptions=grid_options, update_mode=GridUpdateMode.MODEL_CHANGED, allow_unsafe_jscode=True, key="company_grid" ) # 处理点击事件 if "cellClick" in st.session_state: show_company_info(st.session_state.cellClick)
内容的提问来源于stack exchange,提问作者engineer-x
相关产品推荐
相关产品推荐

