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

使用GridUpdateMode.NO_UPDATE获取Streamlit-AgGrid复选框选中行

解决Streamlit AgGrid在NO_UPDATE模式下获取选中行并避免卡顿的方案

核心方案

使用GridUpdateMode.NO_UPDATE禁用自动渲染更新,通过自定义JavaScript在提交按钮点击时主动获取AgGrid的选中行数据,再将数据传递回Python端处理GET请求,全程避免频繁组件重渲染导致的卡顿。

完整代码实现

import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode
import pandas as pd
import json
import requests

# 生成模拟测试数据(2000行20列)
def generate_test_data():
    data = {f"Col_{i}": range(2000) for i in range(20)}
    df = pd.DataFrame(data)
    # 添加唯一ID列,确保AgGrid能准确识别行
    df["row_id"] = df.index.astype(str)
    return df

st.title("AgGrid 批量选中提交示例")

# 初始化会话状态,存储选中行数据
if "selected_rows" not in st.session_state:
    st.session_state.selected_rows = []

df = generate_test_data()

# 配置AgGrid选项
gb = GridOptionsBuilder.from_dataframe(df)
gb.configure_selection("multiple", use_checkbox=True, groupSelectsChildren=True)
# 设置行唯一标识,避免排序/过滤后选中行混乱
gb.configure_grid_options(getRowId="params.data.row_id")
grid_options = gb.build()

# 渲染AgGrid,使用NO_UPDATE模式
grid_response = AgGrid(
    df,
    gridOptions=grid_options,
    update_mode=GridUpdateMode.NO_UPDATE,
    allow_unsafe_jscode=True,  # 允许自定义JS代码
    height=500,
    fit_columns_on_grid_load=True
)

# 隐藏文本框,用于JS传递选中行数据
hidden_input = st.text_input("", value="", key="hidden_selected", label_visibility="hidden")

# 自定义JS:点击提交按钮时获取选中行并写入隐藏文本框
submit_js = """
<script>
document.getElementById('submit_btn').addEventListener('click', function() {
    // 获取AgGrid实例
    const gridDiv = document.querySelector('.ag-root-wrapper');
    const gridApi = gridDiv?.__agGridInstance?.api;
    if (!gridApi) return;
    
    // 获取选中行数据,转换为JSON字符串
    const selectedRows = gridApi.getSelectedRows();
    const jsonData = JSON.stringify(selectedRows);
    
    // 写入隐藏的Streamlit文本框
    const hiddenInput = document.querySelector('[data-testid="stTextInput"][aria-label=""]');
    if (hiddenInput) {
        hiddenInput.value = jsonData;
        // 触发Streamlit组件更新
        hiddenInput.dispatchEvent(new Event('input', {bubbles: true}));
    }
});
</script>
"""

# 渲染提交按钮和JS代码
st.markdown(submit_js, unsafe_allow_html=True)
st.button("提交选中行", key="submit_btn")

# 处理选中行数据,发送GET请求
if st.session_state.hidden_selected:
    try:
        selected_rows = json.loads(st.session_state.hidden_selected)
        # 转换为DataFrame方便处理(可选)
        selected_df = pd.DataFrame(selected_rows).drop("row_id", axis=1)
        
        # 生成查询参数(这里根据需求调整参数格式)
        query_params = {
            "selected_rows": selected_df.to_json(orient="records")
            # 或者按列拆分参数,比如"col0": ",".join(selected_df["Col_0"].astype(str))
        }
        
        # 发送GET请求(替换为目标URL)
        target_url = "https://your-target-url.com/api"
        response = requests.get(target_url, params=query_params)
        
        st.success(f"请求发送成功,响应状态码:{response.status_code}")
        st.subheader("选中行预览")
        st.dataframe(selected_df)
        
        # 清空隐藏输入,避免重复处理
        st.session_state.hidden_selected = ""
    except Exception as e:
        st.error(f"处理失败:{str(e)}")

关键细节说明

  • GridUpdateMode.NO_UPDATE:彻底禁用AgGrid的自动更新触发,避免每次选中行都触发Streamlit重渲染,从根源解决卡顿问题。
  • getRowId配置:设置行唯一标识,确保在排序、过滤、分页后,AgGrid仍能准确识别选中的行,不会出现选中行混乱的情况。
  • 自定义JS传递数据:利用Streamlit的隐藏文本框作为JS和Python的桥梁,点击按钮时主动获取选中行并传递,而非依赖AgGrid的内置回调。
  • 会话状态处理:通过st.session_state存储临时数据,避免页面重绘丢失选中状态,同时确保请求发送后清空缓存,防止重复提交。

纯客户端备选方案(无需后端请求)

如果只需要在客户端处理选中行(比如导出、本地展示),可以修改JS部分直接处理数据,无需传递回Python:

// 修改提交按钮的JS逻辑,直接在客户端处理
document.getElementById('submit_btn').addEventListener('click', function() {
    const gridDiv = document.querySelector('.ag-root-wrapper');
    const gridApi = gridDiv?.__agGridInstance?.api;
    if (!gridApi) return;
    
    const selectedRows = gridApi.getSelectedRows();
    // 客户端处理逻辑:比如导出为CSV
    const csvContent = "data:text/csv;charset=utf-8," 
        + Object.keys(selectedRows[0]).join(",") + "\n"
        + selectedRows.map(e => Object.values(e).join(",")).join("\n");
    
    const encodedUri = encodeURI(csvContent);
    const link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "selected_rows.csv");
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:02:34