initial commit, functinal software
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
"""Theme helpers."""
|
||||
|
||||
from orisys_app_shared.theme.qss import build_qss, clear_theme_cache, color, load_colors
|
||||
|
||||
__all__ = ["build_qss", "clear_theme_cache", "color", "load_colors"]
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"window_bg": "#121316",
|
||||
"panel_bg": "#1a1c20",
|
||||
"panel_border": "#2a2d33",
|
||||
"text_primary": "#e8eaed",
|
||||
"text_secondary": "#9aa0a6",
|
||||
"accent": "#536dce",
|
||||
"accent_hover": "#6b82d9",
|
||||
"button_bg": "#2a2d33",
|
||||
"button_hover": "#3a3f47",
|
||||
"input_bg": "#0f1012",
|
||||
"input_border": "#3a3f47",
|
||||
"menu_bg": "#1a1c20",
|
||||
"menu_hover": "#2a2d33",
|
||||
"plot_fn": "#8ab4f8",
|
||||
"plot_fx": "#34a853",
|
||||
"plot_fy": "#fbbc04",
|
||||
"plot_bg": "#121316",
|
||||
"plot_grid": "#2a2d33",
|
||||
"arrow_canvas": "#121316",
|
||||
"danger": "#ea4335",
|
||||
"success": "#34a853"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"window_bg": "#f5f6f8",
|
||||
"panel_bg": "#ffffff",
|
||||
"panel_border": "#d0d4dc",
|
||||
"text_primary": "#1a1c20",
|
||||
"text_secondary": "#5f6368",
|
||||
"accent": "#536dce",
|
||||
"accent_hover": "#3f56b5",
|
||||
"button_bg": "#e8eaed",
|
||||
"button_hover": "#d0d4dc",
|
||||
"input_bg": "#ffffff",
|
||||
"input_border": "#c0c4cc",
|
||||
"menu_bg": "#ffffff",
|
||||
"menu_hover": "#e8eaed",
|
||||
"plot_fn": "#1a73e8",
|
||||
"plot_fx": "#188038",
|
||||
"plot_fy": "#f9ab00",
|
||||
"plot_bg": "#ffffff",
|
||||
"plot_grid": "#e0e3e8",
|
||||
"arrow_canvas": "#eef0f3",
|
||||
"danger": "#d93025",
|
||||
"success": "#188038"
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
"""Build Qt stylesheets from theme color token JSON (no hex in widgets)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _theme_dir() -> Path:
|
||||
return Path(__file__).resolve().parent
|
||||
|
||||
|
||||
@lru_cache(maxsize=4)
|
||||
def load_colors(theme: str = "dark") -> dict[str, str]:
|
||||
name = "colors_dark.json" if theme != "light" else "colors_light.json"
|
||||
path = _theme_dir() / name
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
if not isinstance(data, dict):
|
||||
raise ValueError(f"Invalid theme file: {path}")
|
||||
return {str(k): str(v) for k, v in data.items()}
|
||||
|
||||
|
||||
def build_qss(theme: str = "dark") -> str:
|
||||
c = load_colors(theme)
|
||||
return f"""
|
||||
QWidget {{
|
||||
background-color: {c['window_bg']};
|
||||
color: {c['text_primary']};
|
||||
font-family: "Microsoft YaHei", "Segoe UI", sans-serif;
|
||||
font-size: 13px;
|
||||
}}
|
||||
QMainWindow, QDialog {{
|
||||
background-color: {c['window_bg']};
|
||||
}}
|
||||
QMenuBar {{
|
||||
background-color: {c['menu_bg']};
|
||||
color: {c['text_primary']};
|
||||
border-bottom: 1px solid {c['panel_border']};
|
||||
}}
|
||||
QMenuBar::item:selected {{
|
||||
background-color: {c['menu_hover']};
|
||||
}}
|
||||
QMenu {{
|
||||
background-color: {c['menu_bg']};
|
||||
color: {c['text_primary']};
|
||||
border: 1px solid {c['panel_border']};
|
||||
}}
|
||||
QMenu::item:selected {{
|
||||
background-color: {c['menu_hover']};
|
||||
}}
|
||||
QToolBar {{
|
||||
background-color: {c['panel_bg']};
|
||||
border-bottom: 1px solid {c['panel_border']};
|
||||
spacing: 8px;
|
||||
padding: 4px;
|
||||
}}
|
||||
QPushButton {{
|
||||
background-color: {c['button_bg']};
|
||||
color: {c['text_primary']};
|
||||
border: 1px solid {c['panel_border']};
|
||||
border-radius: 4px;
|
||||
padding: 6px 12px;
|
||||
}}
|
||||
QPushButton:hover {{
|
||||
background-color: {c['button_hover']};
|
||||
}}
|
||||
QPushButton:disabled {{
|
||||
color: {c['text_secondary']};
|
||||
}}
|
||||
QComboBox, QLineEdit, QSpinBox {{
|
||||
background-color: {c['input_bg']};
|
||||
color: {c['text_primary']};
|
||||
border: 1px solid {c['input_border']};
|
||||
border-radius: 4px;
|
||||
padding: 4px 8px;
|
||||
min-height: 24px;
|
||||
}}
|
||||
QLabel#panelTitle {{
|
||||
color: {c['text_secondary']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
QLabel#panelMeta {{
|
||||
color: {c['text_secondary']};
|
||||
font-weight: 500;
|
||||
padding-right: 8px;
|
||||
}}
|
||||
QFrame#contentPanel {{
|
||||
background-color: {c['panel_bg']};
|
||||
border: 1px solid {c['panel_border']};
|
||||
border-radius: 6px;
|
||||
}}
|
||||
QStatusBar {{
|
||||
background-color: {c['panel_bg']};
|
||||
color: {c['text_secondary']};
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
def color(theme: str, key: str, default: str = "#888888") -> str:
|
||||
return load_colors(theme).get(key, default)
|
||||
|
||||
|
||||
def clear_theme_cache() -> None:
|
||||
load_colors.cache_clear()
|
||||
Reference in New Issue
Block a user