修改Calman灰阶中结果图显示、修改UI主题样式应用

This commit is contained in:
xinzhu.yin
2026-06-04 10:36:15 +08:00
parent 3aa975c4d3
commit 49d82da8b9
16 changed files with 597 additions and 210 deletions

View File

@@ -36,37 +36,188 @@ def _is_dark(color: str) -> bool:
return (r * 299 + g * 587 + b * 114) / 1000 < 128
def apply_modern_styles() -> None:
"""注册或刷新现代化样式集。可在主题切换后再次调用。"""
style = ttk.Style()
theme = style.colors # ttkbootstrap.style.Colors
def _contrast_text(color: str, *, dark_text: str, light_text: str) -> str:
return dark_text if _is_dark(color) else light_text
bg = theme.bg # 主背景
fg = theme.fg # 主前景
def get_theme_palette() -> dict[str, str]:
"""返回当前主题的语义色板,供 ttk / tk 自定义控件共用。"""
style = ttk.Style()
theme = style.colors
bg = theme.bg
fg = theme.fg
primary = theme.primary
secondary = theme.secondary
success = theme.success
info = theme.info
warning = theme.warning
danger = theme.danger
dark = theme.dark
border = theme.border
inputbg = theme.inputbg
inputfg = getattr(theme, "inputfg", fg)
dark_theme = _is_dark(bg)
select_bg = getattr(theme, "selectbg", _mix(primary, bg, 0.30 if dark_theme else 0.12))
select_fg = getattr(theme, "selectfg", "#ffffff" if _is_dark(select_bg) else fg)
# 卡片背景:在主背景上轻微偏移,营造层级感
card_bg = _mix(bg, "#ffffff", 0.04) if dark_theme else _mix(bg, "#000000", 0.025)
card_border = _mix(bg, fg, 0.18) if dark_theme else _mix(bg, "#000000", 0.10)
# 配置项 header 用 secondary 主题色
header_bg = secondary
header_fg = "#ffffff" if _is_dark(secondary) else "#1a1a1a"
if dark_theme:
card_bg = _mix(bg, "#ffffff", 0.04)
card_border = _mix(bg, fg, 0.18)
header_fg = _contrast_text(
"#444A51",
dark_text="#ffffff",
light_text="#1a1a1a",
)
sidebar_bg = _mix(dark, bg, 0.18)
sidebar_hover = _mix(sidebar_bg, "#ffffff", 0.07)
sidebar_selected = _mix(sidebar_bg, "#ffffff", 0.14)
sidebar_fg = _mix(fg, "#ffffff", 0.04)
sidebar_muted = _mix(sidebar_fg, sidebar_bg, 0.45)
muted_fg = _mix(fg, bg, 0.32)
disabled_fg = _mix(fg, bg, 0.42)
disabled_bg = _mix(inputbg, bg, 0.18)
disabled_border = _mix(border, fg, 0.22)
readonly_bg = _mix(inputbg, "#ffffff", 0.06)
success_fg = _mix(success, "#ffffff", 0.08)
warning_fg = _mix(warning, "#ffffff", 0.06)
info_fg = _mix(info, "#ffffff", 0.06)
statusbar_bg = _mix(bg, "#ffffff", 0.06)
tooltip_bg = _mix(inputbg, bg, 0.08)
tooltip_fg = inputfg
tooltip_border = _mix(border, fg, 0.20)
surface_alt_bg = _mix(card_bg, "#ffffff", 0.05)
surface_hover_bg = _mix(card_bg, "#ffffff", 0.09)
badge_bg = _mix(danger, bg, 0.12)
badge_fg = "#ffffff"
focus = _mix(primary, "#ffffff", 0.18)
config_bg = _mix("#444A51", bg, 0.30)
else:
card_bg = inputbg
card_border = border
header_fg = bg
config_bg = _mix(primary, bg, 0.25)
sidebar_bg = _mix(primary, bg, 0.82)
sidebar_hover = _mix(primary, bg, 0.72)
sidebar_selected = primary
sidebar_fg = fg
sidebar_muted = _mix(fg, sidebar_bg, 0.35)
muted_fg = _mix(fg, bg, 0.38)
disabled_fg = _mix(fg, bg, 0.55)
disabled_bg = _mix(bg, border, 0.18)
disabled_border = _mix(border, bg, 0.18)
readonly_bg = _mix(inputbg, primary, 0.04)
success_fg = success
warning_fg = _mix(warning, fg, 0.18)
info_fg = info
statusbar_bg = _mix(bg, dark, 0.04)
tooltip_bg = inputbg
tooltip_fg = inputfg
tooltip_border = border
surface_alt_bg = _mix(bg, dark, 0.03)
surface_hover_bg = _mix(bg, dark, 0.05)
badge_bg = danger
badge_fg = "#ffffff"
focus = _mix(primary, bg, 0.20)
return {
"bg": bg,
"fg": fg,
"primary": primary,
"secondary": secondary,
"success": success,
"info": info,
"warning": warning,
"danger": danger,
"border": border,
"input_bg": inputbg,
"input_fg": inputfg,
"select_bg": select_bg,
"select_fg": select_fg,
"card_bg": card_bg,
"card_border": card_border,
"header_fg": header_fg,
"sidebar_bg": sidebar_bg,
"sidebar_hover": sidebar_hover,
"sidebar_selected": sidebar_selected,
"sidebar_fg": sidebar_fg,
"sidebar_muted": sidebar_muted,
"muted_fg": muted_fg,
"disabled_fg": disabled_fg,
"disabled_bg": disabled_bg,
"disabled_border": disabled_border,
"readonly_bg": readonly_bg,
"success_fg": success_fg,
"warning_fg": warning_fg,
"info_fg": info_fg,
"statusbar_bg": statusbar_bg,
"tooltip_bg": tooltip_bg,
"tooltip_fg": tooltip_fg,
"tooltip_border": tooltip_border,
"surface_alt_bg": surface_alt_bg,
"surface_hover_bg": surface_hover_bg,
"badge_bg": badge_bg,
"badge_fg": badge_fg,
"focus": focus,
"config_bg": config_bg,
}
def apply_listbox_theme(widget) -> None:
"""将 tk.Listbox 颜色同步到当前主题。"""
palette = get_theme_palette()
widget.configure(
background=palette["input_bg"],
foreground=palette["input_fg"],
highlightbackground=palette["border"],
highlightcolor=palette["focus"],
selectbackground=palette["select_bg"],
selectforeground=palette["select_fg"],
disabledforeground=palette["disabled_fg"],
)
def apply_tooltip_theme(toplevel, label) -> None:
"""将 tooltip 的 tk.Toplevel / Label 同步到当前主题。"""
palette = get_theme_palette()
toplevel.configure(background=palette["tooltip_border"])
label.configure(
bg=palette["tooltip_bg"],
fg=palette["tooltip_fg"],
highlightbackground=palette["tooltip_border"],
)
def apply_modern_styles() -> None:
"""注册或刷新现代化样式集。可在主题切换后再次调用。"""
style = ttk.Style()
palette = get_theme_palette()
bg = palette["bg"]
fg = palette["fg"]
primary = palette["primary"]
secondary = palette["secondary"]
info = palette["info"]
card_bg = palette["card_bg"]
card_border = palette["card_border"]
header_bg = palette["config_bg"]
header_fg = palette["header_fg"]
dark_theme = _is_dark(bg)
header_hover_bg = _mix(secondary, "#ffffff", 0.08) if _is_dark(secondary) else _mix(secondary, "#000000", 0.08)
preview_fg = _mix(header_fg, header_bg, 0.35)
sidebar_bg = _mix(dark, bg, 0.18) if dark_theme else _mix(primary, "#000000", 0.10)
sidebar_hover = _mix(sidebar_bg, "#ffffff", 0.07) if dark_theme else _mix(sidebar_bg, "#000000", 0.06)
sidebar_selected = _mix(sidebar_bg, "#ffffff", 0.14) if dark_theme else _mix(sidebar_bg, "#000000", 0.10)
# 侧栏背景在浅色主题下也偏深,文字颜色需按侧栏亮度自适应,避免“黑字不明显”。
sidebar_fg = "#F4F8FD" if _is_dark(sidebar_bg) else _mix(fg, bg, 0.05)
sidebar_muted = _mix(sidebar_fg, sidebar_bg, 0.45)
sidebar_bg = palette["sidebar_bg"]
sidebar_hover = palette["sidebar_hover"]
sidebar_selected = palette["sidebar_selected"]
sidebar_fg = palette["sidebar_fg"]
sidebar_muted = palette["sidebar_muted"]
muted_fg = palette["muted_fg"]
disabled_fg = palette["disabled_fg"]
disabled_bg = palette["disabled_bg"]
disabled_border = palette["disabled_border"]
readonly_bg = palette["readonly_bg"]
success_fg = palette["success_fg"]
warning_fg = palette["warning_fg"]
# ---------------- 卡片 ----------------
style.configure(
@@ -134,6 +285,12 @@ def apply_modern_styles() -> None:
font=("Segoe UI", 9),
)
# ---------------- 通用文字语义 ----------------
style.configure("Muted.TLabel", background=bg, foreground=muted_fg)
style.configure("SuccessState.TLabel", background=bg, foreground=success_fg)
style.configure("WarningState.TLabel", background=bg, foreground=warning_fg)
style.configure("InfoState.TLabel", background=bg, foreground=palette["info_fg"])
# ---------------- 顶部工具条 ----------------
style.configure("Toolbar.TFrame", background=bg, borderwidth=0)
# 工具条上的次要按钮(清理配置等)
@@ -168,9 +325,17 @@ def apply_modern_styles() -> None:
style.configure(
"SidebarBrand.TLabel",
background=brand_bg,
foreground="#ffffff",
foreground=palette["badge_fg"],
font=("Segoe UI Semibold", 12),
)
style.configure(
"SidebarBadge.TLabel",
background=palette["badge_bg"],
foreground=palette["badge_fg"],
font=("微软雅黑", 8, "bold"),
anchor="center",
padding=(6, 2),
)
# ---------------- 结果区无边框标题行 ----------------
style.configure("ResultHeader.TFrame", background=bg, borderwidth=0)
@@ -182,7 +347,7 @@ def apply_modern_styles() -> None:
)
# ---------------- 状态栏 ----------------
statusbar_bg = _mix(bg, "#000000", 0.06) if not dark_theme else _mix(bg, "#ffffff", 0.06)
statusbar_bg = palette["statusbar_bg"]
statusbar_fg = _mix(fg, bg, 0.15)
style.configure(
"StatusBar.TFrame",
@@ -204,6 +369,33 @@ def apply_modern_styles() -> None:
padding=(10, 4),
)
# ---------------- 深色禁用态 / 只读态增强 ----------------
style.map(
"TLabel",
foreground=[("disabled", disabled_fg)],
)
style.map(
"TButton",
foreground=[("disabled", disabled_fg)],
background=[("disabled", disabled_bg)],
bordercolor=[("disabled", disabled_border)],
darkcolor=[("disabled", disabled_bg)],
lightcolor=[("disabled", disabled_bg)],
)
style.map(
"TEntry",
foreground=[("disabled", disabled_fg)],
fieldbackground=[("disabled", disabled_bg), ("readonly", readonly_bg)],
bordercolor=[("disabled", disabled_border), ("readonly", disabled_border)],
)
style.map(
"TCombobox",
foreground=[("disabled", disabled_fg), ("readonly", fg)],
fieldbackground=[("disabled", disabled_bg), ("readonly", readonly_bg)],
bordercolor=[("disabled", disabled_border), ("readonly", disabled_border)],
arrowcolor=[("disabled", disabled_fg), ("readonly", muted_fg)],
)
# ---------------- Sidebar 按钮(保留兼容名) ----------------
style.configure(
"Sidebar.TButton",
@@ -225,7 +417,7 @@ def apply_modern_styles() -> None:
style.configure(
"SidebarSelected.TButton",
background=sidebar_selected,
foreground="#ffffff",
foreground=_contrast_text(sidebar_selected, dark_text=palette["badge_fg"], light_text=sidebar_fg),
font=("Segoe UI Semibold", 10),
padding=(18, 9),
borderwidth=0,