Spaces:
Sleeping
Sleeping
File size: 5,310 Bytes
f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 d70d84b f2c0e49 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
import streamlit as st
import toml
from pathlib import Path
import os
import time
class ThemeSelector:
def __init__(
self, themes_dir=".streamlit/themes", config_path=".streamlit/config.toml"
):
self.themes_dir = Path(themes_dir)
self.config_path = Path(config_path)
self.themes = {}
self.load_themes()
def load_themes(self):
"""加载所有主题文件"""
self.themes = {}
if not self.themes_dir.exists():
return
for theme_file in self.themes_dir.glob("*.toml"):
try:
theme_data = toml.load(theme_file)
# 从根级别获取theme_name和theme_poem
theme_name = theme_data.get("theme_name", theme_file.stem)
theme_poem = theme_data.get("theme_poem", "")
theme_config = theme_data.get("theme", {})
self.themes[theme_name] = {
"file": theme_file,
"name": theme_name,
"poem": theme_poem,
"config": theme_config,
}
except Exception as e:
st.warning(f"读取主题文件 {theme_file} 失败: {e}")
def get_current_theme(self):
"""获取当前主题名称"""
if not self.config_path.exists():
return None
try:
# config = toml.load(self.config_path)
# # 从根级别读取theme_name
# current_theme_name = config.get("theme") or {}
# current_theme_name = current_theme_name.get("theme_name")
# return current_theme_name
theme_toml = self.config_path.parent / "theme.toml"
theme = toml.load(theme_toml)
return theme.get("theme_name")
except Exception:
return None
def apply_theme(self, theme_name):
"""应用选定的主题"""
if theme_name not in self.themes:
st.error(f"主题 '{theme_name}' 不存在")
return False
try:
# 确保配置目录存在
self.config_path.parent.mkdir(parents=True, exist_ok=True)
# 读取现有配置或创建新配置
config = {}
if self.config_path.exists():
try:
config = toml.load(self.config_path)
except Exception:
config = {}
# 添加根级别的theme_name和theme_poem
# config["theme_name"] = self.themes[theme_name]["name"]
# config["theme_poem"] = self.themes[theme_name]["poem"]
# 更新主题配置
theme_config = self.themes[theme_name]["config"].copy()
# theme_config["theme_name"] = self.themes[theme_name]["name"]
# theme_config["theme_poem"] = self.themes[theme_name]["poem"]
config["theme"] |= theme_config
# 写入配置文件
with open(self.config_path, "w", encoding="utf-8") as f:
toml.dump(config, f)
theme_toml = self.config_path.parent / "theme.toml"
with open(theme_toml, "w", encoding="utf-8") as f:
toml.dump(
dict(
theme_name=self.themes[theme_name]["name"],
theme_poem=self.themes[theme_name]["poem"],
),
f,
)
return True
except Exception as e:
st.error(f"应用主题失败: {e}")
return False
def render_theme_selector(self):
"""渲染主题选择器UI"""
if not self.themes:
st.warning("未找到可用主题")
return
theme_names = list(self.themes.keys())
current_theme = self.get_current_theme()
# 确定当前选中的索引
current_index = 0
if current_theme and current_theme in theme_names:
current_index = theme_names.index(current_theme)
# 主题选择下拉菜单
selected_theme = st.selectbox(
"选择主题",
options=theme_names,
index=current_index,
format_func=lambda x: self.themes[x]["name"],
key="theme_selector_widget",
label_visibility="collapsed",
)
# 如果选择了新主题
if selected_theme != current_theme:
if self.apply_theme(selected_theme):
# 显示主题诗句
theme_poem = self.themes[selected_theme]["poem"]
if theme_poem:
st.toast(f"✨ {theme_poem}", icon="🎨")
else:
st.toast(f"已切换到主题: {selected_theme}", icon="🎨")
time.sleep(3)
# 延迟重新运行以应用主题
st.rerun()
return selected_theme
# 全局主题选择器实例
_theme_selector = None
def get_theme_selector():
"""获取全局主题选择器实例"""
global _theme_selector
if _theme_selector is None:
_theme_selector = ThemeSelector()
return _theme_selector
def render_theme_selector():
"""便捷函数:渲染主题选择器"""
return get_theme_selector().render_theme_selector()
|