You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Streamlit的st.markdown中点击HTML按钮触发st.dialog弹窗

解决方案:通过JS+隐藏组件实现HTML按钮触发Streamlit Dialog

要实现st.markdown中的HTML按钮触发st.dialog,核心是解决前端HTML事件与后端Streamlit状态同步的问题(因为HTML按钮无法直接调用Python函数)。以下是可行的实现方案:

实现思路

  1. 用会话状态变量show_dialog控制弹窗的显示/隐藏
  2. 新增一个隐藏的Streamlit文本输入组件,作为前后端交互的桥梁
  3. 给HTML按钮添加JS点击事件,修改隐藏输入框的值并触发输入事件,触发后端回调更新会话状态
  4. 根据会话状态决定是否显示弹窗

完整代码

import streamlit as st

# 初始化会话状态,控制弹窗显示
if "show_dialog" not in st.session_state:
    st.session_state.show_dialog = False

# 回调函数:当隐藏输入值变化时,更新弹窗状态
def trigger_dialog():
    if st.session_state.hidden_trigger == "open_dialog":
        st.session_state.show_dialog = True
        # 重置触发值,避免重复触发
        st.session_state.hidden_trigger = ""

# 隐藏的文本输入组件(仅作为交互桥梁)
st.text_input(
    label="",
    key="hidden_trigger",
    on_change=trigger_dialog,
    label_visibility="hidden",
    disabled=False
)

# 定义弹窗内容
@st.dialog("POP UP WINDOW")
def show_rgpd_popup():
    st.write("This is pop up window")
    # 关闭弹窗时重置状态
    if st.button("关闭"):
        st.session_state.show_dialog = False
        st.rerun()

# 根据会话状态显示弹窗
if st.session_state.show_dialog:
    show_rgpd_popup()

# 渲染HTML按钮(保留st.markdown方式)
st.markdown("""
<div class="navbar-buttons">
    <a href="javascript:void(0)" onclick="
        // 定位到隐藏的文本输入框
        const hiddenInput = document.querySelector('[data-testid=\"stTextInput\"] input');
        // 设置触发值并触发输入事件,触发后端回调
        hiddenInput.value = 'open_dialog';
        hiddenInput.dispatchEvent(new Event('input'));
    " class="navbar-text">POP UP BUTTON</a>
</div>
""", unsafe_allow_html=True)

st.title("TEST JS & HTML IN STREAMLIT")
st.caption('A live demo')

关键细节说明

  • 隐藏组件的作用:Streamlit的组件状态变化会自动触发后端重新运行,因此用隐藏的st.text_input作为中间层,让JS可以通过修改它的值来通知后端更新状态
  • JS事件处理javascript:void(0)避免点击链接时页面跳转,dispatchEvent(new Event('input'))模拟用户输入,确保Streamlit能捕获到值的变化
  • 状态重置:弹窗关闭时调用st.rerun()刷新页面,确保状态同步

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

火山引擎 最新活动