Source code for xraylabtool.gui.theme_manager

from __future__ import annotations

from PySide6.QtCore import QObject, QSettings, Signal
from PySide6.QtWidgets import QApplication

from .style import (
    DARK_THEME,
    LIGHT_THEME,
    ColorPalette,
    apply_pyqtgraph_theme,
    apply_theme,
)


[docs] class ThemeManager(QObject): """Manages application theme state and persistence.""" theme_changed = Signal(str) # Emits "light" or "dark"
[docs] def __init__(self, app: QApplication) -> None: super().__init__() self._app = app self._settings = QSettings("AnlXray", "XRayLabTool") # Ensure we read as string, QSettings can be tricky with types self._current_mode = str(self._settings.value("gui/theme_mode", "light")) # Validate stored value if self._current_mode not in ("light", "dark"): self._current_mode = "light"
@property def current_palette(self) -> ColorPalette: """Get the active ColorPalette object.""" return DARK_THEME if self._current_mode == "dark" else LIGHT_THEME
[docs] def set_theme(self, mode: str) -> None: """Set the active theme mode.""" if mode not in ("light", "dark"): return if mode == self._current_mode: return self._current_mode = mode self._settings.setValue("gui/theme_mode", mode) self.apply(self._app) self.theme_changed.emit(mode)
[docs] def get_theme(self) -> str: """Get current theme mode string.""" return self._current_mode
[docs] def toggle_theme(self) -> None: """Toggle between light and dark modes.""" new_mode = "dark" if self._current_mode == "light" else "light" self.set_theme(new_mode)
[docs] def apply(self, app_instance: QApplication) -> None: """Apply current theme to application and global resources.""" # Update Qt styles apply_theme(app_instance, self.current_palette) # Update PyQtGraph styles apply_pyqtgraph_theme(self.current_palette) # Force palette update on app (sometimes needed for dynamic switches) app_instance.setPalette(self.current_palette.to_qpalette())