Files
Network-tools/core/ui/theme.py
T
2026-06-08 13:39:59 +08:00

179 lines
5.8 KiB
Python

import tkinter as tk
from tkinter import ttk
COLORS = {
"bg": "#f4f7fb",
"panel": "#ffffff",
"panel_alt": "#f8fafc",
"topbar": "#071424",
"sidebar": "#0b1b2f",
"sidebar_hover": "#132943",
"sidebar_active": "#2f6df6",
"text": "#0f1f35",
"muted": "#5f7088",
"border": "#dce5f0",
"border_dark": "#cbd8e6",
"primary": "#2f6df6",
"primary_dark": "#1f56d8",
"primary_soft": "#edf4ff",
"danger": "#ef4444",
"danger_soft": "#fff1f2",
"success": "#16a36a",
"success_soft": "#dcfce7",
"warning": "#b7791f",
"console_bg": "#07111f",
"console_fg": "#dbeafe",
"console_muted": "#93a8c5",
"console_accent": "#22d3ee",
}
FONT_BODY = ("Microsoft YaHei UI", 10)
FONT_SMALL = ("Microsoft YaHei UI", 9)
FONT_TITLE = ("Microsoft YaHei UI", 18, "bold")
FONT_SECTION = ("Microsoft YaHei UI", 12, "bold")
FONT_MONO = ("Consolas", 10)
def apply_theme(root: tk.Tk) -> None:
root.configure(bg=COLORS["bg"])
style = ttk.Style(root)
try:
style.theme_use("clam")
except tk.TclError:
pass
style.configure(".", font=FONT_BODY)
style.configure("TFrame", background=COLORS["bg"])
style.configure("Panel.TFrame", background=COLORS["panel"])
style.configure("Alt.TFrame", background=COLORS["panel_alt"])
style.configure("Page.TFrame", background=COLORS["bg"])
style.configure("TLabel", background=COLORS["panel"], foreground=COLORS["text"])
style.configure("Muted.TLabel", background=COLORS["panel"], foreground=COLORS["muted"], font=FONT_SMALL)
style.configure("PageMuted.TLabel", background=COLORS["bg"], foreground=COLORS["muted"], font=FONT_SMALL)
style.configure("Title.TLabel", background=COLORS["bg"], foreground=COLORS["text"], font=FONT_TITLE)
style.configure("Section.TLabel", background=COLORS["panel"], foreground=COLORS["text"], font=FONT_SECTION)
style.configure(
"TEntry",
fieldbackground="#ffffff",
foreground=COLORS["text"],
bordercolor=COLORS["border"],
lightcolor=COLORS["border"],
darkcolor=COLORS["border"],
relief="solid",
padding=(10, 8),
)
style.map("TEntry", bordercolor=[("focus", COLORS["primary"]), ("disabled", COLORS["border"])])
style.configure(
"TCombobox",
fieldbackground="#ffffff",
foreground=COLORS["text"],
bordercolor=COLORS["border"],
arrowcolor=COLORS["muted"],
relief="solid",
padding=(10, 7),
)
style.map("TCombobox", bordercolor=[("focus", COLORS["primary"])], fieldbackground=[("readonly", "#ffffff")])
style.configure(
"Primary.TButton",
background=COLORS["primary"],
foreground="#ffffff",
borderwidth=1,
bordercolor=COLORS["primary"],
focusthickness=0,
padding=(16, 9),
)
style.map(
"Primary.TButton",
background=[("active", COLORS["primary_dark"]), ("disabled", "#a9c0f4")],
bordercolor=[("active", COLORS["primary_dark"]), ("disabled", "#a9c0f4")],
foreground=[("disabled", "#eef4ff")],
)
style.configure(
"Secondary.TButton",
background="#ffffff",
foreground=COLORS["primary"],
borderwidth=1,
bordercolor="#bcd0ff",
lightcolor="#bcd0ff",
darkcolor="#bcd0ff",
focusthickness=0,
padding=(16, 9),
)
style.map(
"Secondary.TButton",
background=[("active", COLORS["primary_soft"]), ("disabled", "#f1f5f9")],
foreground=[("disabled", "#9aa8ba")],
bordercolor=[("active", COLORS["primary"]), ("disabled", COLORS["border"])],
)
style.configure(
"Danger.TButton",
background="#ffffff",
foreground=COLORS["danger"],
borderwidth=1,
bordercolor="#fca5a5",
lightcolor="#fca5a5",
darkcolor="#fca5a5",
focusthickness=0,
padding=(16, 9),
)
style.map("Danger.TButton", background=[("active", COLORS["danger_soft"])], bordercolor=[("active", COLORS["danger"])])
style.configure(
"Treeview",
background="#ffffff",
fieldbackground="#ffffff",
foreground=COLORS["text"],
rowheight=30,
bordercolor=COLORS["border"],
borderwidth=1,
)
style.configure(
"Treeview.Heading",
background=COLORS["panel_alt"],
foreground=COLORS["muted"],
font=("Microsoft YaHei UI", 9, "bold"),
relief="flat",
padding=(8, 7),
)
style.map("Treeview", background=[("selected", COLORS["primary_soft"])], foreground=[("selected", COLORS["text"])])
style.configure("TNotebook", background=COLORS["panel"], borderwidth=0)
style.configure("TNotebook.Tab", padding=(18, 8), background=COLORS["panel_alt"], foreground=COLORS["muted"])
style.map("TNotebook.Tab", background=[("selected", "#ffffff")], foreground=[("selected", COLORS["primary"])])
style.configure(
"Modern.Vertical.TScrollbar",
gripcount=0,
background="#d7e0ec",
darkcolor="#d7e0ec",
lightcolor="#d7e0ec",
troughcolor=COLORS["bg"],
bordercolor=COLORS["bg"],
arrowcolor=COLORS["muted"],
relief="flat",
width=10,
)
style.map("Modern.Vertical.TScrollbar", background=[("active", "#bfccdc")])
def build_app_icon(size: int = 64) -> tk.PhotoImage:
image = tk.PhotoImage(width=size, height=size)
image.put(COLORS["sidebar"], to=(0, 0, size, size))
image.put(COLORS["primary"], to=(8, 8, size - 8, size - 8))
image.put("#5eead4", to=(16, 20, 27, 31))
image.put("#ffffff", to=(37, 20, 48, 31))
image.put("#ffffff", to=(16, 38, 27, 49))
image.put("#5eead4", to=(37, 38, 48, 49))
image.put("#ffffff", to=(24, 25, 41, 29))
image.put("#ffffff", to=(24, 42, 41, 46))
image.put("#ffffff", to=(21, 28, 25, 42))
image.put("#ffffff", to=(39, 28, 43, 42))
return image