Streamlit实现:点击DataFrame的Player单元格显示对应图片
直接用HTML渲染DataFrame没法实现你要的交互,因为Streamlit的静态HTML无法触发会话状态更新。得改用Streamlit的交互式组件,下面给两种可行方案:
方案一:用Streamlit原生st.data_editor(无需额外依赖)
这个方案利用会话状态控制显示逻辑,通过表格选中事件触发状态切换:
import streamlit as st import pandas as pd # 初始化会话状态变量,控制显示列表/图片 if "show_image" not in st.session_state: st.session_state.show_image = False if "selected_path" not in st.session_state: st.session_state.selected_path = "" columns_to_display = ['Rating', 'Player', 'Position', 'Age', 'Value', 'Wages', 'Contract'] def switch_to_image(): # 获取选中行的索引,提取对应图片路径 selected_rows = st.session_state.player_table["edited_rows"] if selected_rows: row_idx = next(iter(selected_rows.keys())) st.session_state.selected_path = players.iloc[row_idx]["Path"] st.session_state.show_image = True # 根据状态显示内容 if not st.session_state.show_image: # 用data_editor展示表格,禁止编辑仅允许选中 st.data_editor( players[columns_to_display], key="player_table", on_change=switch_to_image, use_container_width=True, # 设置列左对齐,匹配你原来的HTML样式 column_config={ col: st.column_config.Column(align="left") for col in columns_to_display }, disabled=columns_to_display, hide_index=True ) else: # 显示选中球员的图片 if st.session_state.selected_path: st.image(st.session_state.selected_path, caption="Player Profile") # 返回按钮切回列表 if st.button("回到球员列表"): st.session_state.show_image = False st.session_state.selected_path = ""
说明:
- 点击表格任意行都会触发切换,如果需要仅点击Player列才触发,原生组件做不到,得用下面的第三方组件方案。
方案二:用streamlit-aggrid实现精确单元格点击(需额外依赖)
这个库支持自定义单元格点击事件,能严格只响应Player列的点击:
- 先安装依赖:
pip install streamlit-aggrid
- 实现代码:
import streamlit as st import pandas as pd from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode # 初始化会话状态 if "show_image" not in st.session_state: st.session_state.show_image = False if "selected_path" not in st.session_state: st.session_state.selected_path = "" columns_to_display = ['Rating', 'Player', 'Position', 'Age', 'Value', 'Wages', 'Contract'] if not st.session_state.show_image: # 配置表格选项 gb = GridOptionsBuilder.from_dataframe(players[columns_to_display]) # 设置Player列的点击事件:仅点击该列时才选中行 gb.configure_grid_options( onCellClicked="""function(params) { if (params.column.colId === 'Player') { params.api.setSelectedNodes([params.node]); } }""", suppressRowClickSelection=True # 禁止整行点击选中 ) gb.configure_selection(selection_mode="single", use_checkbox=False) grid_options = gb.build() # 渲染表格 grid_response = AgGrid( players[columns_to_display], gridOptions=grid_options, update_mode=GridUpdateMode.SELECTION_CHANGED, allow_unsafe_jscode=True, # 允许自定义JS逻辑 use_container_width=True ) # 检测选中行,切换到图片显示 selected_rows = grid_response["selected_rows"] if selected_rows: st.session_state.selected_path = selected_rows[0]["Path"] st.session_state.show_image = True else: st.image(st.session_state.selected_path, caption="Player Profile") if st.button("回到球员列表"): st.session_state.show_image = False st.session_state.selected_path = ""
说明:
- 通过自定义JS代码,只有点击Player列的单元格时才会触发选中逻辑,完全匹配你的需求。
内容的提问来源于stack exchange,提问作者Pedro Leite
相关产品推荐
相关产品推荐

