修改Calman灰阶中结果图显示、修改UI主题样式应用
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user