1
1
mirror of https://github.com/KenanZhu/AutoLibrary.git synced 2026-06-21 00:43:03 +08:00

fix(theme): 主题系统交叉审查缺陷修复

启动恢复:
- _initializeAppearance 自定义主题加载失败时调用 clearTheme 回退配色方案

列表校验:
- listThemes 同时校验 info.json 和 theme.qss 完整性
- 损坏的主题文件记录 LogManager 警告并跳过
- 按 (名称, 作者) 去重,同一作者同名主题仅保留一个

导入保护:
- importTheme 新增 (名称, 作者) 冲突检查
- applyTheme 缺少 theme.qss 时抛出明确 ValueError

状态一致性:
- saveAndApply 在 syncRadioFromNeedTheme 后重新采集 THEME 再保存
- __original_theme / __original_custom_theme 随每次 Apply 同步更新
- Reset 按钮恢复组合框到原始位置并刷新状态标签

代码质量:
- 提取 _colorSchemeFor 静态方法消除 applyTheme/clearTheme 中的重复映射
- 移除未使用的 _applyTheme 死代码
- _active_style_name 默认值从 '' 改为 'Fusion'
- 日志调用统一使用 LogManager
- _applyCustomTheme 异常时通过 LogManager 记录详细错误

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 00:46:05 +08:00
parent 62f8ec3d91
commit 44dbde3355
3 changed files with 134 additions and 141 deletions
+46 -36
View File
@@ -31,8 +31,9 @@ from PySide6.QtWidgets import (
)
import managers.config.ConfigManager as ConfigManager
from managers.theme.ThemeManager import (
ThemeManager,
from managers.log.LogManager import instance as logInstance
from managers.theme.ThemeManager import(
getActiveStyle,
instance as themeInstance
)
@@ -43,31 +44,34 @@ from interfaces.ConfigProvider import (
)
_active_style_name = ""
def _setActiveStyleName(
name: str
def _applyCustomTheme(
name: str,
fallback_theme: str = "system"
):
global _active_style_name
_active_style_name = name
def _applyTheme(
theme: str
):
global _active_style_name
app : QApplication | None = QApplication.instance()
if not app:
if not name:
themeInstance().clearTheme(fallback_theme)
return
if theme == "dark":
app.styleHints().setColorScheme(Qt.ColorScheme.Dark)
elif theme == "light":
app.styleHints().setColorScheme(Qt.ColorScheme.Light)
try:
themeInstance().applyTheme(name)
except Exception as e:
logInstance().getLogger("ALSettingsWidget").warning(
f"无法应用自定义主题 '{name}',回退到 {fallback_theme} 外观: {e}"
)
themeInstance().clearTheme(fallback_theme)
def _themeToReadable(
need_theme: str
) -> str:
if need_theme == "dark":
return "深色"
elif need_theme == "light":
return "浅色"
elif need_theme == "both":
return "所有"
else:
app.styleHints().setColorScheme(Qt.ColorScheme.Unknown)
app.setStyle(QStyleFactory.create(_active_style_name))
return "未知"
def _restartApp(
):
@@ -75,6 +79,7 @@ def _restartApp(
QApplication.instance().quit()
QProcess.startDetached(sys.executable, sys.argv)
class ALSettingsWidget(QWidget, Ui_ALSettingsWidget):
settingsWidgetIsClosed = Signal()
@@ -126,12 +131,6 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget):
self.StyleComboBox.clear()
self.StyleComboBox.addItems(QStyleFactory.keys())
def currentStyleKey(
self
) -> str:
return _active_style_name
def connectSignals(
self
):
@@ -181,7 +180,7 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget):
custom_theme = self.__cfg_mgr.get(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, "")
self.__original_theme = theme
self.__original_custom_theme = custom_theme
self.__original_style = self.currentStyleKey()
self.__original_style = getActiveStyle()
if theme == "light":
self.LightThemeRadio.setChecked(True)
elif theme == "dark":
@@ -224,7 +223,7 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget):
need_theme = t.get("need_theme", "both")
brief = t.get("brief", "没有相关简介")
self.ThemeInfoLabel.setText(
f"<b>{name}</b> - 适用于 <i>{ThemeManager.themeToReadable(need_theme)}</i> 主题<br>"
f"<b>{name}</b> - 适用于 <i>{_themeToReadable(need_theme)}</i> 主题<br>"
f"作者:{author}<br><br>"
f"{brief}"
)
@@ -267,15 +266,18 @@ 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)
themeInstance().applyThemeOrClear(custom_theme, theme)
_applyCustomTheme(custom_theme, theme)
self.syncRadioFromNeedTheme(custom_theme)
# Re-read theme after syncRadioFromNeedTheme — the radio may have
# changed to match the custom theme's need_theme
theme, _, _ = self.collectSettings()
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.THEME, theme)
_applyTheme(theme)
self.setNavigationIcons()
self.updateThemeStatus()
self.updateThemeInfo()
self.__original_style = self.currentStyleKey()
self.__original_theme = theme
self.__original_custom_theme = custom_theme if custom_theme else ""
self.__original_style = getActiveStyle()
def maybeRestart(
self
@@ -351,7 +353,14 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget):
):
self.ThemeComboBox.blockSignals(True)
self.ThemeComboBox.setCurrentIndex(0)
if self.__original_custom_theme:
idx = self.ThemeComboBox.findText(self.__original_custom_theme)
if idx >= 0:
self.ThemeComboBox.setCurrentIndex(idx)
else:
self.ThemeComboBox.setCurrentIndex(0)
else:
self.ThemeComboBox.setCurrentIndex(0)
self.ThemeComboBox.blockSignals(False)
if self.__original_theme == "light":
self.LightThemeRadio.setChecked(True)
@@ -359,7 +368,8 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget):
self.DarkThemeRadio.setChecked(True)
else:
self.SystemThemeRadio.setChecked(True)
themeInstance().clearTheme(self.__original_theme)
_applyCustomTheme(self.__original_custom_theme, self.__original_theme)
self.updateThemeStatus()
self.updateThemeInfo()
@Slot()