一. 功能说明
基于 Streamlit框架,开发了一些提供操作界面的python小工具集,具有一定的实用和学习价值。源代码可通过 Github 或 Gitee 进行下载。 下图为工具列表清单。

二. Streamlit 开发小技巧
在开发过程中,有一些实用技巧,整理如下,便于使用和理解代码。
1. 隐藏 Streamlit 的顶部菜单栏
def hide_system_menu():
"""
隐藏 Streamlit 的顶部菜单栏 , 并调整高度
"""
hide_menu_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
.block-container {
padding-top: 0px !important; /* 调整这个值来改变顶部空间 */
}
</style>
"""
st.markdown(hide_menu_style, unsafe_allow_html=True)
隐藏前的效果:
st.markdown("""# 📚 Streamlit 小技巧""")
隐藏后的效果:
hide_system_menu()
st.markdown("""# 📚 Streamlit 小技巧""")

2. 增加上下组件间的间距
根据实际需要,设置高度的像素值(如 50px),来调节间距
st.markdown("<div style='height:50px'></div>", unsafe_allow_html=True)
3. 横向布局组件
利用 st.columns() 实现组件的横向布局,并可通过设置分栏的个数和比例值,实现特定效果。其中分栏的总个数可以大于实际使用的分栏数,且无需都使用,只用于分割空间。
例1:3个按钮居中均匀布局
cols = st.columns(3)
cols[0].button("确定")
cols[1].button("取消")
cols[2].button("删除")

例2: 2个按钮居左,1个按钮居右
cols = st.columns([1, 1, 3, 1])
cols[0].button("确定")
cols[1].button("取消")
cols[3].button("删除")

例3:实现界面的左右容器布局
col_left, col_right = st.columns([1, 2])
with col_left:
st.markdown("**参数设置**")
with st.container(border=True):
v_parameters = st.text_area(label="**输入参数**",
height=150,
label_visibility="collapsed")
with col_right:
st.markdown("**结果显示**")
with st.container(border=True):
v_results = st.text_area(label="**结果值**",
height=150,
label_visibility="collapsed")

4. 布局内容的动态调整
Streamlit 的组件位置是按代码执行顺序来布局的,但可以通过 st.empty(),先设置占位符,后续再填充需要的组件内容,可实现指定布局位置上的内容动态调整。 如点击【确定】按钮,在其前面布局的消息栏位置上实时显示相关信息
# 消息占位符,可用于显示消息内容
message_holder = st.empty()
if st.button("确定"):
message_holder.empty()
with message_holder.container():
st.warning("**确定前请先确认参数!**")

5. 动态生成多个组件
利用 st.columns() ,结合数组处理,可以动态进行分栏处理,然后可以在相应分栏单元中,设置需要的组件,如 checkbox, image 等。以下例子,是动态生成多个 checkbox。
cells = []
rows = 3
cols = 4
for i in range(0, rows):
cells.append(st.columns(cols))
for j in range(0, cols):
index = i * cols + j
cells[i][j].checkbox(label=str(index),
key=index,
value=True if index in [1, 3, 5] else False,
label_visibility="collapsed")

6. Session的安全处理
streamlit 提供的 session_state, 若键值不存在,会出现报错 。可提供一个安全处理的类,方便使用。
class Session:
"""
streamlit 的 Session 处理工具类,主要增加了对 key_name 的判断
"""
@staticmethod
def get_value(key_name, default_value=""):
if key_name not in st.session_state:
return default_value
else:
return st.session_state[key_name]
@staticmethod
def set_value(key_name, value):
st.session_state[key_name] = value
@staticmethod
def del_key(key_name):
if key_name in st.session_state:
del st.session_state[key_name]
7. 目录输入框
可用于需要输入目录名参数的小工具中。在【目录输入框】中可直接输入目录名;通过【浏览】按钮,可打开资源管理器,自动定位到所输入的目录。通过手工复制资源管理器中的目录名,再粘贴到输入框中。(这种方式代码比较简单,又可结合资源管理器进行目录选择,手工复制也还方便)
import os
import streamlit as st
cols_dir = st.columns([5, 1])
with cols_dir[0]:
v_file_folder = st.text_input("**图片的目录**", value="c:\\")
with cols_dir[1]:
st.markdown("<div style='height:28px'></div>", unsafe_allow_html=True)
if st.button("**浏览**"):
show_file = v_file_folder
if not os.path.exists(show_file):
show_file = "c:\\"
os.startfile(show_file)

8. 目录选择框
利用 tkinter 的文件夹对话框,在Streamlit页面上,提供目录选择框:通过点击【浏览】按钮,可在弹出的对话框中,进行目录的选择定位,通过按【选择文件夹】按钮,将返回所选的目录信息到页面输入框。 由于手工输入目录信息,在取值一致性上还有些问题未解决,输入框目前设置为了只读。(该方式效果完整一些,但代码比较复杂,可重用性还需提高。代码中用到的 Session.get_value(), Session.set_value(), 为本文第 6 点提供的 Session 类)
import streamlit as st
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
root.wm_attributes('-topmost', 1)
# 用于通过Session记录目录名,在多个页面间保持数据一致性
KEY_FOLDER_NAME = "choice_folder_button:folder_name"
cols_dir = st.columns([5, 1])
with cols_dir[0]:
# 选择完后,需要重新设置显示路径值,可用占位符来控制
choice_holder = st.empty()
v_file_folder = choice_holder.text_input("**图片的目录**",
value=Session.get_value(KEY_FOLDER_NAME, "c:\\"),
disabled=True,
key="text_dir_first")
with cols_dir[1]:
st.markdown("<div style='height:28px'></div>", unsafe_allow_html=True)
if st.button("**浏览**"):
choice_file = filedialog.askdirectory(master=root, initialdir=v_file_folder)
if choice_file:
Session.set_value(KEY_FOLDER_NAME, choice_file)
v_file_folder = choice_holder.text_input("**图片的目录**",
value=Session.get_value(KEY_FOLDER_NAME),
disabled=True,
key="text_dir_second")



1226

被折叠的 条评论
为什么被折叠?



