如何用st.empty和占位符实现Streamlit应用自动更新?
解决Streamlit应用自动更新数据的问题
你的代码存在两个核心问题导致无法自动更新:
- 最后一行的
placeholder1.empty()会立即清空刚渲染的指标内容,导致页面显示异常 - 没有设置自动触发应用重新运行(rerun)的机制,Streamlit默认不会主动刷新页面
修正方案
1. 移除清空占位符的代码
直接删除placeholder1.empty(),这行代码会抵消你在占位符内渲染的所有内容。
2. 添加自动刷新机制
根据你的Streamlit版本,选择以下两种方法之一:
方法一:使用st.autorefresh(推荐,适用于Streamlit 1.22.0+)
这个方法是官方提供的自动刷新API,无需循环,配置简单:
import streamlit as st import pandas as pd import time # 配置每5秒自动刷新一次,可根据需求调整interval(单位:毫秒) st.autorefresh(interval=5000, key="sensor_refresh") # 定义获取最新传感器数据的函数(替换成你实际的数据获取逻辑,比如读数据库/API) def get_latest_sensor_data(): # 示例:模拟获取最新数据,实际场景替换为你的数据读取代码 return pd.DataFrame({ "Sensor 1": [round(pd.np.random.uniform(20, 30), 1)], "Sensor 2": [round(pd.np.random.uniform(20, 30), 1)], "Sensor 3": [round(pd.np.random.uniform(20, 30), 1)], "Sensor 4": [round(pd.np.random.uniform(20, 30), 1)] }) placeholder1 = st.empty() # 每次刷新时重新渲染指标 with placeholder1: # 每次刷新必须重新获取最新数据,不能只在脚本开头读一次 sensors_df3 = get_latest_sensor_data() st.metric(label="Sensor 1 RH", value=sensors_df3['Sensor 1'].iloc[-1]) st.metric(label="Sensor 2 RH", value=sensors_df3['Sensor 2'].iloc[-1]) st.metric(label="Sensor 3 RH", value=sensors_df3['Sensor 3'].iloc[-1]) st.metric(label="Sensor 4 RH", value=sensors_df3['Sensor 4'].iloc[-1])
方法二:使用while循环+time.sleep(适用于旧版本Streamlit)
如果你的Streamlit版本较低,不支持st.autorefresh,可以用循环实现:
import streamlit as st import pandas as pd import time placeholder1 = st.empty() # 定义获取最新数据的函数(同上) def get_latest_sensor_data(): return pd.DataFrame({ "Sensor 1": [round(pd.np.random.uniform(20, 30), 1)], "Sensor 2": [round(pd.np.random.uniform(20, 30), 1)], "Sensor 3": [round(pd.np.random.uniform(20, 30), 1)], "Sensor 4": [round(pd.np.random.uniform(20, 30), 1)] }) while True: sensors_df3 = get_latest_sensor_data() with placeholder1: st.metric(label="Sensor 1 RH", value=sensors_df3['Sensor 1'].iloc[-1]) st.metric(label="Sensor 2 RH", value=sensors_df3['Sensor 2'].iloc[-1]) st.metric(label="Sensor 3 RH", value=sensors_df3['Sensor 3'].iloc[-1]) st.metric(label="Sensor 4 RH", value=sensors_df3['Sensor 4'].iloc[-1]) # 控制更新间隔,这里是5秒 time.sleep(5)
关键注意事项
- 必须每次刷新都重新获取数据:如果你的
sensors_df3是在脚本开头一次性加载的,即使页面刷新,数据也不会更新,必须把数据获取逻辑放在每次渲染的流程里。 - 修正方法名:原代码中的
Sensor1.metric是错误写法,Streamlit的指标组件是st.metric。
内容的提问来源于stack exchange,提问作者james tim
相关产品推荐
相关产品推荐

