当前位置: 首页 > news >正文

streamlit实现非原生的按钮触发效果 + flask实现带信息的按钮触发

目录

  • 简介
  • 不携带信息的触发
    • 隐藏指定st.button(label, key)
    • 触发button的html
    • 代码汇总
  • 携带信息的触发
    • 为什么需要携带信息
    • 前端JavaScript修改
    • flask处理
    • 总代码


简介

由于streamlit可以同时在实现前后端结合,非常方便,但是这也造成了user难以方便的对页面的组件进行位置控制,本文将使用streamlit+flask,实现普通按钮触发与携带信息

不携带信息的触发

隐藏指定st.button(label, key)

这里给出隐藏指定button的方法

hidden_button_class = 'div[data-testid="stElementContainer"].st-key-hidden_trigger button[data-testid="stBaseButton-secondary"]'
hide_button_style = f"""
<style>
{hidden_button_class} {{display: none;}}
</style>
"""  # 如果已经使用f方法,想使用花括号就必须使用{{代替{
st.markdown(hide_button_style, unsafe_allow_html=True)

hidden_button中的st-key-hidden_trigger可以根据你的button的key进行修改
如果key = “test”, 这里就改为st-key-test,就可以实现对某个指定button的隐藏!
当然,把.st-key-{key_name}删掉,就可以直接隐藏所有button

触发button的html

通过在页面插入iframe,在iframe内进行JavaScript操作,实现对隐藏button的模拟点击

all_html = f"""<script>function handleButtonClick(event) {{// 查找隐藏的streamlit按钮按钮const hiddenButton = parent.document.querySelector('div[data-testid="stElementContainer"].st-key-hidden_trigger button[data-testid="stBaseButton-secondary"]');if (hiddenButton) {{// 触发点击hiddenButton.click();}}}}// 事件委托处理点击document.addEventListener('click', function(event) {{if (event.target.matches('.detail-btn')) {{handleButtonClick(event);}}}});</script><button class="detail-btn" data-title="test">点我</button> // 这里button的样式可以随便修改,根据需求"""
st.components.v1.html(all_html)

但是需要注意:外部的button样式对v1.html的样式不生效,内部的button样式对v1.html同样不生效
所以所有内部样式css必须写入all_html中

代码汇总

如果想要实现

import streamlit as sthide_button_style = """
<style>
div[data-testid="stElementContainer"].st-key-hidden_trigger button[data-testid="stBaseButton-secondary"] {display: none;}
</style>
"""
st.markdown(hide_button_style, unsafe_allow_html=True)def generate_button():all_html = f"""<script>function handleButtonClick(event) {{// 查找隐藏按钮const hiddenButton = parent.document.querySelector('div[data-testid="stElementContainer"].st-key-hidden_trigger button[data-testid="stBaseButton-secondary"]');if (hiddenButton) {{// 触发点击hiddenButton.click();}}}}// 事件委托处理点击document.addEventListener('click', function(event) {{if (event.target.matches('.detail-btn')) {{handleButtonClick(event);}}}});</script><button class="detail-btn" data-title="test">点我</button>"""st.components.v1.html(all_html)returngenerate_button()
if st.button("hidden_trigger", key="hidden_trigger"):st.success("可以修改为你想实现的功能~")
st.button("no_hidden_trigger", key="no_hidden_trigger")

css样式指定隐藏的button
我们在点击自己设定的button后,触发了隐藏的button,没有触发不隐藏的button


携带信息的触发

为什么需要携带信息

假设有这么一个股票信息管理界面,很明显,如果使用streamlit原生的组件,将难以实现查看详情的按钮效果(嵌入在内容卡片中),而一支股票有很多信息(意味着更多的查看详情),为每一个查看详情都提供一个隐藏button,会导致无意义的内存占用,所以可以通过设置一个隐藏按钮,并通过flask后端处理数据,接收并传递信息
在这里插入图片描述

前端JavaScript修改

def generate_button():all_html = f"""<script>function handleButtonClick(event) {{const title = event.target.dataset.title;// 查找隐藏按钮const hiddenButton = parent.document.querySelector('div[data-testid="stElementContainer"].st-key-hidden_trigger button[data-testid="stBaseButton-secondary"]');if (hiddenButton) {{// 触发点击hiddenButton.click();// 发送数据到Flaskfetch('http://localhost:8000/api/data', {{method: 'POST',headers: {{'Content-Type': 'application/json',}},body: JSON.stringify({{title, stock}}),}}).then(response => response.json()).then(data => console.log('Success:', data)).catch(error => console.error('Error:', error));}}}}// 事件委托处理点击document.addEventListener('click', function(event) {{if (event.target.matches('.detail-btn')) {{handleButtonClick(event);}}}});</script><button class="detail-btn" data-title="test">点我</button>"""st.components.v1.html(all_html)return

关键在于向flask发送一个post请求,携带我们需要传递的信息(发送json串,解析为dict)
event.target.dataset是(<button class=“detail-btn” data-title=“test”>点我</button>)中,data-title的值
所以:event.target.dataset.title = “test”
利用这个属性来传递信息

flask处理

from flask import Flask, request, jsonify
from flask_cors import CORS
import requestsapp = Flask(__name__)
CORS(app)@app.route('/api/data', methods=['POST'])
def receive_data():data = request.get_json()title = process_data(data["title"])with open("data.txt", "w", encoding="utf-8") as f:f.write(title)return jsonify({200: "成功"})def process_data(data):# 数据处理逻辑return data.upper()if __name__ == '__main__':app.run(port=8000, debug=True)

一定需要CORS(),这意味着能不能实现跨域接收信息,只有加上这个才能实现网页发送信息,而flask后端能够接收网页发送的信息
同时在接收信息之后,能够将信息写入data.txt供其他文件调用(信息传递)

总代码

import timeimport streamlit as stdef generate_button():all_html = f"""<script>function handleButtonClick(event) {{const title = event.target.dataset.title;const stock = event.target.dataset.stock;// 查找隐藏按钮const hiddenButton = parent.document.querySelector('div[data-testid="stElementContainer"].st-key-hidden_trigger button[data-testid="stBaseButton-secondary"]');if (hiddenButton) {{// 触发点击hiddenButton.click();// 发送数据到Flaskfetch('http://localhost:8000/api/data', {{method: 'POST',headers: {{'Content-Type': 'application/json',}},body: JSON.stringify({{title, stock}}),}}).then(response => response.json()).then(data => console.log('Success:', data)).catch(error => console.error('Error:', error));}}}}// 事件委托处理点击document.addEventListener('click', function(event) {{if (event.target.matches('.detail-btn')) {{handleButtonClick(event);}}}});</script><button class="detail-btn" data-title="test">点我</button>"""st.components.v1.html(all_html)returngenerate_button()
if st.button("hidden_trigger", key="hidden_trigger"):time.sleep(0.05)  # 让flask能够写入信息,设置一小段时间延时with open("data.txt", "r", encoding="utf-8") as fr:content = fr.read()  # 读取携带的信息st.success("接收到信息:" + content)

相关文章:

  • 前端浏览器窗口交互完全指南:从基础操作到高级控制
  • 论文导读 - 基于大规模测量与多任务深度学习的电子鼻系统实现目标识别、浓度预测与状态判断
  • [计算机科学#3]:布尔逻辑 (计算机数学基础)
  • 【中级软件设计师】编译和解释程序的翻译阶段、符号表 (附软考真题)
  • Lua 第10部分 模式匹配
  • 【嵌入式八股22】排序算法与哈希算法
  • 辞九门回忆
  • windows安装docker,发现没有hyper
  • WSL2里手动安装Docker 遇坑
  • 14【模块学习】74HC595:使用学习
  • SpringMVC 前后端数据交互 中文乱码
  • 微服务基础-Ribbon
  • 同样开源的自动化工作流工具n8n和Dify对比
  • 从零搭建云原生后端系统 —— 一次真实项目实践分享
  • 迷你世界UGC3.0脚本Wiki触发器脚本交互
  • 云原生--核心组件-容器篇-4-认识Dockerfile文件(镜像创建的基础文件和指令介绍)
  • 企业数据赋能 | 应用模板分享:汽车销售仪表板
  • 《一键式江湖:Docker Compose中间件部署108式》开篇:告别“配置地狱”,从此笑傲云原生武林!》
  • 以科技之力,启智慧出行 —— 阅读《NVIDIA 自动驾驶安全报告》及观看实验室视频有感
  • 【计算机视觉】CV实战项目- Four-Flower:基于TensorFlow的花朵分类实战指南
  • 国家发改委:建立实施育儿补贴制度
  • 国家发展改革委:我们对实现今年经济社会发展目标任务充满信心
  • 民调显示特朗普执政百日支持率为80年来美历任总统最低
  • 银川市长信箱被指“已读乱回”,官方通报:对相关责任人问责处理
  • 国家核安全局局长:我国核电进入大规模建设高峰期,在建规模超其他国家总和
  • 第二部以“法典”命名的法律!生态环境法典编纂迈出“关键步”