diff --git a/ui/main.py b/ui/main.py index 9e3fd5e..b4916fb 100644 --- a/ui/main.py +++ b/ui/main.py @@ -13,6 +13,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import os +from dataclasses import dataclass +from typing import Callable + from PySide6.QtGui import QIcon, QShowEvent from qfluentwidgets import FluentIcon, MSFluentWindow, NavigationItemPosition, MessageBox, setThemeColor @@ -20,40 +24,99 @@ from ui import MAIN_THEME_COLOR, BLUE_BACKGROUND_COLOR from ui.pyui.about_ui import AboutWidget from ui.pyui.achievement_ui import AchievementWidget from ui.pyui.defense_ui import DefenseWidget -# from ui.pyui.picker_ui import PickerWidget +from ui.pyui.picker_ui import PickerWidget from ui.pyui.test_ui import TestWidget from utils.function import RELEASE_ENV +@dataclass(frozen=True) +class InterfaceSpec: + key: str + factory: Callable[[], object] + icon: FluentIcon + nav_text: str + position: NavigationItemPosition = NavigationItemPosition.TOP + enabled: bool = True + + class MainWindow(MSFluentWindow): def __init__(self): super().__init__() setThemeColor(MAIN_THEME_COLOR) self.setCustomBackgroundColor(BLUE_BACKGROUND_COLOR, BLUE_BACKGROUND_COLOR) - - self.achievementInterface = AchievementWidget('Achievement Interface', self) - self.defenseInterface = DefenseWidget('Defense Interface', self) - self.aboutInterface = AboutWidget('About Interface', self) - # self.pickerInterface = PickerWidget('Picker Interface', self) - if not RELEASE_ENV: - self.testInterface = TestWidget('Test Interface', self) - - self.achievementInterface.error.connect(self.showError) - self.defenseInterface.errorSignal.connect(self.showError) - # self.pickerInterface.errorSignal.connect(self.showError) + self.interface_specs = self.build_interface_specs() + self.interfaces = self.create_interfaces(self.interface_specs) + self.bind_error_handlers() self.initNavigation() self.initWindow() - def initNavigation(self): - self.addSubInterface(self.achievementInterface, FluentIcon.SPEED_HIGH, '达成度') - self.addSubInterface(self.defenseInterface, FluentIcon.FEEDBACK, '答辩') - # self.addSubInterface(self.pickerInterface, FluentIcon.PEOPLE, '提问') - if not RELEASE_ENV: - self.addSubInterface(self.testInterface, FluentIcon.VIEW, '测试') + def build_interface_specs(self) -> list[InterfaceSpec]: + return [ + InterfaceSpec( + key="achievement", + factory=lambda: AchievementWidget('Achievement Interface', self), + icon=FluentIcon.SPEED_HIGH, + nav_text='达成度', + enabled=True, + ), + InterfaceSpec( + key="defense", + factory=lambda: DefenseWidget('Defense Interface', self), + icon=FluentIcon.FEEDBACK, + nav_text='答辩', + enabled=True, + ), + InterfaceSpec( + key="picker", + factory=lambda: PickerWidget('Picker Interface', self), + icon=FluentIcon.PEOPLE, + nav_text='提问', + enabled=not RELEASE_ENV, + ), + InterfaceSpec( + key="test", + factory=lambda: TestWidget('Test Interface', self), + icon=FluentIcon.VIEW, + nav_text='测试', + enabled=not RELEASE_ENV, + ), + InterfaceSpec( + key="about", + factory=lambda: AboutWidget('About Interface', self), + icon=FluentIcon.INFO, + nav_text='关于', + position=NavigationItemPosition.BOTTOM, + enabled=True + ), + ] - self.addSubInterface(self.aboutInterface, FluentIcon.INFO, '关于', position=NavigationItemPosition.BOTTOM) + def create_interfaces(self, specs: list[InterfaceSpec]) -> dict[str, object]: + interfaces: dict[str, object] = {} + for spec in specs: + if not spec.enabled: + continue + widget = spec.factory() + interfaces[spec.key] = widget + setattr(self, f"{spec.key}Interface", widget) + return interfaces + + def bind_error_handlers(self): + achievement = self.interfaces.get("achievement") + defense = self.interfaces.get("defense") + + if achievement and hasattr(achievement, "error"): + achievement.error.connect(self.showError) + if defense and hasattr(defense, "errorSignal"): + defense.errorSignal.connect(self.showError) + + def initNavigation(self): + for spec in self.interface_specs: + widget = self.interfaces.get(spec.key) + if not widget: + continue + self.addSubInterface(widget, spec.icon, spec.nav_text, position=spec.position) def initWindow(self): self.resize(900, 700)