diff --git a/src/gui/ALSettingsWidget.py b/src/gui/ALSettingsWidget.py index ab11c84..4450218 100644 --- a/src/gui/ALSettingsWidget.py +++ b/src/gui/ALSettingsWidget.py @@ -34,6 +34,7 @@ import managers.config.ConfigManager as ConfigManager from managers.log.LogManager import instance as logInstance from managers.theme.ThemeManager import( getActiveStyle, + setActiveStyle, instance as themeInstance ) @@ -47,18 +48,20 @@ from interfaces.ConfigProvider import ( def _applyCustomTheme( name: str, fallback_theme: str = "system" -): +) -> bool: if not name: themeInstance().clearTheme(fallback_theme) - return + return True try: themeInstance().applyTheme(name) + return True except Exception as e: logInstance().getLogger("ALSettingsWidget").warning( f"无法应用自定义主题 '{name}',回退到 {fallback_theme} 外观: {e}" ) themeInstance().clearTheme(fallback_theme) + return False def _themeToReadable( need_theme: str @@ -266,7 +269,9 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget): theme, style, custom_theme = self.collectSettings() self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.STYLE, style) self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, custom_theme) - _applyCustomTheme(custom_theme, theme) + setActiveStyle(style) + if not _applyCustomTheme(custom_theme, theme): + self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, "") self.syncRadioFromNeedTheme(custom_theme) # Re-read theme after syncRadioFromNeedTheme — the radio may have # changed to match the custom theme's need_theme diff --git a/src/managers/theme/ThemeManager.py b/src/managers/theme/ThemeManager.py index 412e402..3e77346 100644 --- a/src/managers/theme/ThemeManager.py +++ b/src/managers/theme/ThemeManager.py @@ -19,6 +19,7 @@ from PySide6.QtWidgets import ( QStyleFactory ) +from interfaces.ConfigProvider import CfgKey from managers.config.ConfigManager import instance as configInstance from managers.log.LogManager import instance as logInstance from utils.ThemeUtils import ( @@ -119,35 +120,36 @@ class ThemeManager: if not os.path.isfile(source_path): raise FileNotFoundError(source_path) ext = os.path.splitext(source_path)[1].lower() - if ext == ".qss": - name = os.path.splitext(os.path.basename(source_path))[0] - dest_path = os.path.join(self.__themes_dir, name + ".altheme") - if os.path.exists(dest_path): - raise ValueError(f"主题 '{name}' 已存在") - wrapQssToAtheme(source_path, dest_path, "both") - return name - elif ext == ".altheme": - with zipfile.ZipFile(source_path, "r") as zf: - if "theme.qss" not in zf.namelist(): - raise ValueError("无效的 .altheme: 缺少 theme.qss") - info = readThemeInfo(source_path) - name = info.get("name", os.path.splitext(os.path.basename(source_path))[0]) - safe_name = os.path.basename(name) - dest_path = os.path.join(self.__themes_dir, safe_name + ".altheme") - if os.path.exists(dest_path): - raise ValueError(f"主题 '{safe_name}' 已存在") - # Check for name collision with existing themes by the same author - new_author = info.get("author", "") - for existing in self.listThemes(): - if (existing.get("name", "") == safe_name - and existing.get("author", "") == new_author): - raise ValueError( - f"主题名称 '{safe_name}' (作者 '{new_author}') 已存在" - ) - shutil.copy2(source_path, dest_path) - return safe_name - else: - raise ValueError(f"不支持的文件类型: {ext}") + with self.__lock: + if ext == ".qss": + name = os.path.splitext(os.path.basename(source_path))[0] + dest_path = os.path.join(self.__themes_dir, name + ".altheme") + if os.path.exists(dest_path): + raise ValueError(f"主题 '{name}' 已存在") + wrapQssToAtheme(source_path, dest_path, "both") + return name + elif ext == ".altheme": + with zipfile.ZipFile(source_path, "r") as zf: + if "theme.qss" not in zf.namelist(): + raise ValueError("无效的 .altheme: 缺少 theme.qss") + info = readThemeInfo(source_path) + name = info.get("name", os.path.splitext(os.path.basename(source_path))[0]) + safe_name = os.path.basename(name) + dest_path = os.path.join(self.__themes_dir, safe_name + ".altheme") + if os.path.exists(dest_path): + raise ValueError(f"主题 '{safe_name}' 已存在") + # Check for name collision with existing themes by the same author + new_author = info.get("author", "") + for existing in self.listThemes(): + if (existing.get("name", "") == safe_name + and existing.get("author", "") == new_author): + raise ValueError( + f"主题名称 '{safe_name}' (作者 '{new_author}') 已存在" + ) + shutil.copy2(source_path, dest_path) + return safe_name + else: + raise ValueError(f"不支持的文件类型: {ext}") def listThemes( self @@ -214,7 +216,10 @@ class ThemeManager: os.remove(filepath) if self.__current_theme_name == name: self.__current_theme_name = "" - self.clearTheme("system") + saved_theme = configInstance().get( + CfgKey.GLOBAL.APPEARANCE.THEME, "system" + ) + self.clearTheme(saved_theme) def applyTheme( self,