重构主窗口界面,使用接口规范化界面创建和错误处理逻辑

This commit is contained in:
2026-01-06 18:38:54 +08:00
parent db53baba23
commit a708bbfa72

View File

@@ -13,6 +13,10 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import os
from dataclasses import dataclass
from typing import Callable
from PySide6.QtGui import QIcon, QShowEvent from PySide6.QtGui import QIcon, QShowEvent
from qfluentwidgets import FluentIcon, MSFluentWindow, NavigationItemPosition, MessageBox, setThemeColor 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.about_ui import AboutWidget
from ui.pyui.achievement_ui import AchievementWidget from ui.pyui.achievement_ui import AchievementWidget
from ui.pyui.defense_ui import DefenseWidget 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 ui.pyui.test_ui import TestWidget
from utils.function import RELEASE_ENV 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): class MainWindow(MSFluentWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
setThemeColor(MAIN_THEME_COLOR) setThemeColor(MAIN_THEME_COLOR)
self.setCustomBackgroundColor(BLUE_BACKGROUND_COLOR, BLUE_BACKGROUND_COLOR) self.setCustomBackgroundColor(BLUE_BACKGROUND_COLOR, BLUE_BACKGROUND_COLOR)
self.interface_specs = self.build_interface_specs()
self.achievementInterface = AchievementWidget('Achievement Interface', self) self.interfaces = self.create_interfaces(self.interface_specs)
self.defenseInterface = DefenseWidget('Defense Interface', self) self.bind_error_handlers()
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.initNavigation() self.initNavigation()
self.initWindow() self.initWindow()
def initNavigation(self): def build_interface_specs(self) -> list[InterfaceSpec]:
self.addSubInterface(self.achievementInterface, FluentIcon.SPEED_HIGH, '达成度') return [
self.addSubInterface(self.defenseInterface, FluentIcon.FEEDBACK, '答辩') InterfaceSpec(
# self.addSubInterface(self.pickerInterface, FluentIcon.PEOPLE, '提问') key="achievement",
if not RELEASE_ENV: factory=lambda: AchievementWidget('Achievement Interface', self),
self.addSubInterface(self.testInterface, FluentIcon.VIEW, '测试') 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): def initWindow(self):
self.resize(900, 700) self.resize(900, 700)