关于我在使用Steamlit中碰到的问题及解决方案总结

Steamlit 并不支持一个可以预览本地文件的路径选择器(并不上传文件)

解决方案:使用 Python 自带的 tkinter 来完成
参考:【Streamlit 选择文件夹的曲折方案】Streamlit选择文件夹-CSDN博客

import streamlit as st from tkinter import filedialog, Tk  # Set up tkinter root = Tk() root.withdraw() # Make folder picker dialog appear on top of other windows root.wm_attributes('-topmost', 1)  def path_set(label_name: str, segment_name: str, note: str = '', init_path: str = '') -> str: 	''' 	label_name: 标题,用来分割不同的地址获取 	segment_name: 标记,作为 session_state 的 key 以及 streamlit 组件的 key 的生成 	note: 一些提示,写在地址选择上面 	init_path: 初始路径,传入保存在本地的路径或其它 	''' 	# 会话保证刷新网页后不会丢失     if segment_name not in st.session_state:         st.session_state[segment_name] = init_path  	# 选择路径提示     st.markdown('##### ' + label_name)     # 其它文本     st.write(note)          dirname_selected = None     col1, col2 = st.columns([4, 1])     empty_text = col1.empty()     empty_text.text_input(         label='1',          value=st.session_state[segment_name],          label_visibility='collapsed',          autocomplete='on',         key=segment_name + 'input' + 'a',     )     choice = col2.button('浏览文件', key=segment_name + 'button' + 'a')     if choice:         dirname_selected = filedialog.askdirectory(master=root)     if dirname_selected:         st.session_state[segment_name] = dirname_selected     empty_text.text_input(         label='2',          value=st.session_state[segment_name],          label_visibility='collapsed',          autocomplete='on',         key=segment_name + 'input' + 'b',     )     # st.write(st.session_state[segment_name]) # 测试时候用的,用来观察是否成功记录 

思路就是用 st.columns 将页面分两栏,然后使用 st.empty 来占位,将传入的 init_path 保存在 st.session_state 的字典中用来保证刷新后不会丢失,先创建一个 st.text_input来显示初始的 init_path ,然后通过 filedialog.askdirectory 获取到文件地址后,更新 st.empty,使得输入来显示选择的地址。

这个东西花了我很长时间,主要是不太理解 Streamlit 的运作模式,又到处找能用的代码

Streamlit运行

Streamlit 的运行比较反常,不是通过 Python 而是通过 Python 环境中的 Streamlit 命令进行的,很多时候运行和调试起来很麻烦(VSCode上),下面是几种运行方式

VSCode 调试

在项目文件夹下的 .vscode 文件夹,里面的 launch.json 文件中加入

{     // 使用 IntelliSense 了解相关属性。      // 悬停以查看现有属性的描述。     // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387     "version": "0.2.0",     "configurations": [         {             "name": "Streamlit",             "type": "debugpy",             "request": "launch",             "module": "streamlit.web.cli",             "env": {                 "STREAMLIT_ENABLE_COLAB_BACKEND": "true"             },             "args": [                 "run",                 "${file}",                 "--server.port", "667",                 "--server.address", "127.0.0.1"             ]         }     ] } 

这样使用 CodeRunner 中的调试和直接按 F5 调试就可以直接启动了

另附,虽然 Streamlit 有点麻烦,不过正常调试还是可以调试的,打上断点之后启动调试就会卡住,或是随便在代码里加入一个无关紧要的空格(随便改改,不影响代码就行)后,点页面右上角的 Rerun关于我在使用Steamlit中碰到的问题及解决方案总结就OK(没有的话就在那三个点里)

通过 Python 直接运行

其实就是通过 Python 来执行命令

import streamlit.web.cli as stcli import os, sys  if __name__ == "__main__":     if getattr(sys, 'frozen', False):         current_dir = sys._MEIPASS     else:         current_dir = os.path.dirname(os.path.abspath(__file__))     file_path = os.path.join(current_dir, "main.py")      sys.argv = ["streamlit", "run", file_path,          "--server.enableCORS=true", "--server.enableXsrfProtection=false",          "--global.developmentMode=false", "--client.toolbarMode=minimal"]     sys.exit(stcli.main()) 

注:这种是在 Python 环境中的命令,如果 Python 环境没有激活,也可以使用 Python.exe -m streamlit run <streamlit文件> 的形式来运行,例如:关于我在使用Steamlit中碰到的问题及解决方案总结
可以把这个写成批处理脚本,例如:

.runtimepython.exe -m streamlit run .srcmain.py 

关于图表(主要是柱状图)

Streamlit 提供的 图表 可拓展的能力实在是太低,需要做一些精细化调整时就会出现问题(不过要求不太多的话还是很好使的,也很美观),如:

  1. 标签输出不能修改
  2. 不能取消柱状图表鼠标滚轮缩放
  3. 不能取消某个坐标轴的显示
  4. 会乱序

等等,不过毕竟是封装好的简单易用的功能,如果可以忍受瑕疵的话就不要使用第三方的组件(会出现一些奇怪的问题,后面会介绍)所以为了使用更加精细的表格生成,可以通过第三方组件引入 Apache EChart ,其中有两个(在官网上发布的):

  1. ECharts:streamlit-echarts
  2. Raw ECarts:streamlit-raw-echarts

它们本身功能类似,参考链接里的写法,其中配置项 option 的配置方法参考ECharts配置项手册

注:由于在 Python 中,option 表现为一个字典,且 Python 内是没有对应的变量,所以要将 key 写为字符串形式,value 同理,除去传入的数据,布尔类型,数字,基本上剩下的都是字符串形式

它们的不同之处在一些更加细节的地方:

参数可不可以为 JavaScript 函数

它们都包含一个 JScode 函数,可以通过库来导入,但是这个函数在 streamlit-echart 中用处就不大(可能,至少我在尝试使用的时候只能报错),而在 streamlit-raw-echart 中是可以使用的,这个函数可以帮助部分配置项配置 JavaScript函数 ,如:

options = { 	"tooltip": { 		"show": True, 		"trigger": "item", 		"showContent": True, 		"triggerOn": "mousemove", 		"formatter": JsCode('''function(params){return params.name+'<br>抽数:'+ params.data.value +'<br>时间:'+ params.data.time}''') 	}, } 

其中 "formatter" 就对应了一个函数,用来为悬停提示加入部分数据,这种操作在 streamlit-echart 中就只会报错:

MarshallComponentException: ('Could not convert component args to JSON', TypeError('Object of type JsCode is not JSON serializable')) 

大概意思就是说 JsCode 类不能被 Json 序列化

参数名字不同

切记注意两个库中函数名同样是 st_echarts 的两个函数,其中的参数名却不一样

  • streamlit-echarts:options
  • streamlit-raw-echarts:option
发表评论

评论已关闭。

相关文章