- обновлён простой режим: тест цвета и проверка подсветки кнопок объединены в раздел «Тест подсветки» - добавлена проверка подсветки кнопок через 8-й силовой выход с автоматическим коротким тестом - упрощены описания пользовательских проверок и убраны лишние технические подробности из простого режима - изменена раскладка теста цвета, увеличена длительность шага до 1 секунды и убраны описания из PRO-блока - добавлена защита выпадающих списков от случайного изменения колесом мыши - улучшены немодальные PRO-диалоги, настройки соединения и обработка событий COM-порта - обновлены визуальные детали приложения, пользовательские ресурсы, инструкции AGENTS и Release Notes 1.3.0
86 lines
2.2 KiB
Python
86 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Final
|
|
|
|
from PySide6.QtGui import QIcon
|
|
|
|
QTA_AVAILABLE: bool
|
|
|
|
|
|
def _can_write(path: Path) -> bool:
|
|
try:
|
|
path.mkdir(parents=True, exist_ok=True)
|
|
probe = path / ".qta_write_test"
|
|
probe.write_text("ok", encoding="utf-8")
|
|
probe.unlink(missing_ok=True)
|
|
return True
|
|
except OSError:
|
|
return False
|
|
|
|
|
|
def _prepare_qtawesome_env() -> None:
|
|
if os.name != "nt":
|
|
return
|
|
|
|
local_appdata = os.environ.get("LOCALAPPDATA")
|
|
if local_appdata:
|
|
default_fonts_dir = Path(local_appdata) / "Microsoft" / "Windows" / "Fonts"
|
|
if _can_write(default_fonts_dir):
|
|
return
|
|
|
|
fallback_local_appdata = Path.cwd() / ".qta_localappdata"
|
|
fallback_fonts_dir = fallback_local_appdata / "Microsoft" / "Windows" / "Fonts"
|
|
if _can_write(fallback_fonts_dir):
|
|
os.environ["LOCALAPPDATA"] = str(fallback_local_appdata)
|
|
|
|
|
|
_prepare_qtawesome_env()
|
|
|
|
try:
|
|
import qtawesome as qta
|
|
|
|
QTA_AVAILABLE = True
|
|
except Exception:
|
|
qta = None # type: ignore[assignment]
|
|
QTA_AVAILABLE = False
|
|
|
|
|
|
ICON_COLOR_PRIMARY: Final[str] = "#ecfdf5"
|
|
ICON_COLOR_DARK: Final[str] = "#1f2937"
|
|
ICON_COLOR_ACCENT: Final[str] = "#0f766e"
|
|
ICON_COLOR_MUTED: Final[str] = "#64748b"
|
|
ICON_COLOR_DANGER: Final[str] = "#dc2626"
|
|
|
|
|
|
def _current_palette():
|
|
"""Return the active ThemePalette (lazy import to avoid circular deps)."""
|
|
from .theme import get_palette
|
|
|
|
# Local import — settings_service is in a sibling package
|
|
from ..services import settings_service # noqa: E402
|
|
|
|
return get_palette(settings_service.theme_mode(),
|
|
settings_service.theme_accent())
|
|
|
|
|
|
def get_icon_color() -> str:
|
|
"""Icon colour for regular (non-primary) buttons — follows current theme."""
|
|
return _current_palette().icon_default
|
|
|
|
|
|
def get_icon_muted() -> str:
|
|
"""Muted icon colour — follows current theme."""
|
|
return _current_palette().icon_muted
|
|
|
|
|
|
def icon(name: str, *, color: str = ICON_COLOR_DARK) -> QIcon:
|
|
if not QTA_AVAILABLE or qta is None:
|
|
return QIcon()
|
|
|
|
try:
|
|
return qta.icon(name, color=color)
|
|
except Exception:
|
|
return QIcon()
|