修复日志模块深色显示不正确

This commit is contained in:
xinzhu.yin
2026-05-29 08:32:21 +08:00
parent 4498ec501e
commit 21455f3916
4 changed files with 309 additions and 51 deletions

View File

@@ -33,6 +33,55 @@ def _theme_colors():
}
def _normalize_hex(hex_color: str, fallback: str = "#808080") -> str:
"""把颜色字符串规范化为 #RRGGBB非法输入回退到 fallback。"""
if not isinstance(hex_color, str):
return fallback
c = hex_color.strip()
if not c:
return fallback
if c.startswith("#"):
c = c[1:]
if len(c) == 3:
c = "".join(ch * 2 for ch in c)
if len(c) != 6:
return fallback
try:
int(c, 16)
except ValueError:
return fallback
return f"#{c}"
def _hex_to_rgb(hex_color: str):
c = _normalize_hex(hex_color, fallback="#808080").lstrip("#")
return int(c[0:2], 16), int(c[2:4], 16), int(c[4:6], 16)
def _mix(hex_a: str, hex_b: str, ratio: float) -> str:
ratio = max(0.0, min(1.0, ratio))
r1, g1, b1 = _hex_to_rgb(hex_a)
r2, g2, b2 = _hex_to_rgb(hex_b)
r = int(r1 * (1 - ratio) + r2 * ratio)
g = int(g1 * (1 - ratio) + g2 * ratio)
b = int(b1 * (1 - ratio) + b2 * ratio)
return f"#{r:02x}{g:02x}{b:02x}"
def _is_dark(hex_color: str) -> bool:
r, g, b = _hex_to_rgb(hex_color)
return (r * 299 + g * 587 + b * 114) / 1000 < 128
def _auto_text_color(bg_hex: str, fg_hint: str) -> str:
"""根据背景亮度给出稳定可读的文本颜色。"""
bg_hex = _normalize_hex(bg_hex, fallback="#f5f5f5")
fg_hint = _normalize_hex(fg_hint, fallback="#202020")
if _is_dark(bg_hex):
return _mix("#ffffff", fg_hint, 0.25)
return _mix("#000000", fg_hint, 0.25)
class PQLogGUI(ttk.Frame):
VALID_LEVELS = {"info", "success", "warning", "error", "debug", "separator", "blank"}
@@ -132,21 +181,44 @@ class PQLogGUI(ttk.Frame):
def _configure_tags(self):
palette = _theme_colors()
bg = self.log_text.cget("bg") or palette["text_bg"] or palette["bg"]
base_fg = _auto_text_color(bg, palette["fg"])
muted_fg = _mix(base_fg, bg, 0.45)
debug_level_color = _mix(palette["accent"], base_fg, 0.35)
debug_msg_color = _mix(palette["accent"], base_fg, 0.50)
self.log_text.tag_configure("timestamp", foreground=palette["muted"])
self.log_text.tag_configure("level_info", foreground=palette["accent"])
self.log_text.tag_configure("level_success", foreground=palette["success"])
self.log_text.tag_configure("level_warning", foreground=palette["warning"])
self.log_text.tag_configure("level_error", foreground=palette["error"])
self.log_text.tag_configure("level_debug", foreground="#7c3aed")
self.log_text.tag_configure("message", foreground=palette["fg"])
self.log_text.tag_configure("level_debug", foreground=debug_level_color)
self.log_text.tag_configure("message", foreground=base_fg)
self.log_text.tag_configure("message_success", foreground=palette["success"])
self.log_text.tag_configure("message_warning", foreground=palette["warning"])
self.log_text.tag_configure("message_error", foreground=palette["error"])
self.log_text.tag_configure("message_debug", foreground="#6d28d9")
self.log_text.tag_configure("separator", foreground=palette["muted"])
self.log_text.tag_configure("message_debug", foreground=debug_msg_color)
self.log_text.tag_configure("separator", foreground=muted_fg)
self.log_text.tag_configure("traceback", foreground=palette["error"])
self.log_text.tag_configure("blank", spacing1=4, spacing3=4)
def refresh_log_theme(self):
"""主题切换后刷新日志控件的背景和字体颜色。"""
if threading.current_thread() is not threading.main_thread():
self.after(0, self.refresh_log_theme)
return
palette = _theme_colors()
bg = palette["text_bg"]
fg_hint = palette["text_fg"] if palette["text_fg"] else palette["fg"]
fg = _auto_text_color(bg, fg_hint)
self.log_text.configure(
bg=bg,
fg=fg,
insertbackground=fg,
)
self._configure_tags()
def _append_message(self, message, level):
lines = message.splitlines() or [""]
for line in lines: