"""Тёмная тема. Палитра задаётся через QPalette, а не только через QSS: иначе системные диалоги и всплывающие подсказки остались бы светлыми и резали глаза. """ from __future__ import annotations from PySide6.QtCore import QLocale, Qt from PySide6.QtGui import QColor, QPalette BG = "#1c1f24" BG_ALT = "#23272e" SURFACE = "#2b3038" BORDER = "#3a4048" TEXT = "#e6e8ea" TEXT_DIM = "#98a0aa" ACCENT = "#4c9aff" OK = "#4caf7d" WARN = "#d9a441" DANGER = "#e0605e" MUTED = "#6c757d" STATUS_COLORS = { "settled": OK, "open": ACCENT, "due_soon": WARN, "overdue": DANGER, } def apply(app) -> None: app.setStyle("Fusion") # Иначе поля ввода показывают «1,800.00», а таблицы рядом — «1 800,00». QLocale.setDefault(QLocale(QLocale.Russian, QLocale.Russia)) palette = QPalette() palette.setColor(QPalette.Window, QColor(BG)) palette.setColor(QPalette.WindowText, QColor(TEXT)) palette.setColor(QPalette.Base, QColor(BG_ALT)) palette.setColor(QPalette.AlternateBase, QColor(SURFACE)) palette.setColor(QPalette.Text, QColor(TEXT)) palette.setColor(QPalette.Button, QColor(SURFACE)) palette.setColor(QPalette.ButtonText, QColor(TEXT)) palette.setColor(QPalette.ToolTipBase, QColor(SURFACE)) palette.setColor(QPalette.ToolTipText, QColor(TEXT)) palette.setColor(QPalette.Highlight, QColor(ACCENT)) palette.setColor(QPalette.HighlightedText, QColor("#ffffff")) palette.setColor(QPalette.PlaceholderText, QColor(TEXT_DIM)) palette.setColor(QPalette.Link, QColor(ACCENT)) palette.setColor(QPalette.Disabled, QPalette.Text, QColor(MUTED)) palette.setColor(QPalette.Disabled, QPalette.ButtonText, QColor(MUTED)) palette.setColor(QPalette.Disabled, QPalette.WindowText, QColor(MUTED)) app.setPalette(palette) app.setStyleSheet(QSS) QSS = f""" QWidget {{ font-size: 13px; }} QLabel[role="h1"] {{ font-size: 21px; font-weight: 600; }} QLabel[role="h2"] {{ font-size: 15px; font-weight: 600; }} QLabel[role="dim"] {{ color: {TEXT_DIM}; }} QLabel[role="metric"] {{ font-size: 24px; font-weight: 600; }} QFrame[role="card"] {{ background: {SURFACE}; border: 1px solid {BORDER}; border-radius: 8px; }} QFrame[role="banner"] {{ background: #3a2f1c; border: 1px solid {WARN}; border-radius: 6px; }} QListWidget#sidebar {{ background: {BG_ALT}; border: none; border-right: 1px solid {BORDER}; outline: none; padding-top: 8px; }} QListWidget#sidebar::item {{ padding: 10px 16px; margin: 1px 6px; border-radius: 6px; color: {TEXT_DIM}; }} QListWidget#sidebar::item:selected {{ background: {SURFACE}; color: {TEXT}; font-weight: 600; }} QListWidget#sidebar::item:hover {{ color: {TEXT}; }} QPushButton {{ background: {SURFACE}; border: 1px solid {BORDER}; border-radius: 6px; padding: 6px 14px; }} QPushButton:hover {{ border-color: {ACCENT}; }} QPushButton:disabled {{ color: {MUTED}; border-color: {BORDER}; }} QPushButton[role="primary"] {{ background: {ACCENT}; border-color: {ACCENT}; color: #ffffff; font-weight: 600; }} QPushButton[role="primary"]:hover {{ background: #5aa6ff; }} QPushButton[role="danger"]:hover {{ border-color: {DANGER}; color: {DANGER}; }} QLineEdit, QDateEdit, QComboBox, QSpinBox, QDoubleSpinBox, QPlainTextEdit, QTextEdit {{ background: {BG_ALT}; border: 1px solid {BORDER}; border-radius: 6px; padding: 5px 8px; selection-background-color: {ACCENT}; }} QLineEdit:focus, QDateEdit:focus, QComboBox:focus, QSpinBox:focus, QDoubleSpinBox:focus, QPlainTextEdit:focus {{ border-color: {ACCENT}; }} QComboBox::drop-down {{ border: none; width: 18px; }} QComboBox QAbstractItemView {{ background: {BG_ALT}; border: 1px solid {BORDER}; selection-background-color: {ACCENT}; }} QTableWidget, QTreeWidget {{ background: {BG_ALT}; alternate-background-color: {SURFACE}; border: 1px solid {BORDER}; border-radius: 6px; gridline-color: {BORDER}; selection-background-color: {ACCENT}; }} QHeaderView::section {{ background: {SURFACE}; color: {TEXT_DIM}; border: none; border-bottom: 1px solid {BORDER}; padding: 7px 8px; font-weight: 600; }} QTableWidget::item, QTreeWidget::item {{ padding: 4px 6px; }} QProgressBar {{ background: {BG}; border: 1px solid {BORDER}; border-radius: 6px; height: 14px; text-align: center; color: {TEXT}; }} QProgressBar::chunk {{ border-radius: 5px; }} QStatusBar {{ border-top: 1px solid {BORDER}; }} QStatusBar::item {{ border: none; }} QScrollBar:vertical {{ background: transparent; width: 10px; margin: 0; }} QScrollBar::handle:vertical {{ background: {BORDER}; border-radius: 5px; min-height: 30px; }} QScrollBar::handle:vertical:hover {{ background: {MUTED}; }} QScrollBar::add-line, QScrollBar::sub-line {{ height: 0; width: 0; }} QScrollBar:horizontal {{ background: transparent; height: 10px; }} QScrollBar::handle:horizontal {{ background: {BORDER}; border-radius: 5px; min-width: 30px; }} QTabWidget::pane {{ border: 1px solid {BORDER}; border-radius: 6px; }} QTabBar::tab {{ background: transparent; padding: 7px 14px; color: {TEXT_DIM}; border-bottom: 2px solid transparent; }} QTabBar::tab:selected {{ color: {TEXT}; border-bottom-color: {ACCENT}; }} """