修改界面

This commit is contained in:
2025-05-20 02:59:58 +08:00
parent 83b3790e8b
commit 9ca61d5092
13 changed files with 394 additions and 499 deletions

243
ui/pyui/defense_ui.py Normal file
View File

@@ -0,0 +1,243 @@
from typing import Literal, Callable
from functools import wraps
from PySide6.QtCore import Qt, Signal, QThread
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QFileDialog
from qfluentwidgets import GroupHeaderCardWidget, PushButton, IconWidget, InfoBarIcon, \
BodyLabel, PrimaryPushButton, FluentIcon, LineEdit, InfoBar, InfoBarPosition, ProgressBar
from module.worker import DTGWorker
from ui.components.widget import Widget
class InitSettingCard(GroupHeaderCardWidget):
chooseSignal = Signal(str, str)
def __init__(self, parent=None):
super().__init__(parent)
self.setTitle("初始化")
self.setBorderRadius(8)
self.chooseStudentButton = PushButton("打开")
self.chooseQuestionButton = PushButton("打开")
self.chooseStudentButton.setFixedWidth(120)
self.chooseQuestionButton.setFixedWidth(120)
self.stuGroup = self.addGroup(FluentIcon.DOCUMENT, "学生名单", "选择学生名单文件", self.chooseStudentButton)
self.QueGroup = self.addGroup(FluentIcon.DOCUMENT, "题库", "选择题库文件", self.chooseQuestionButton)
self.chooseStudentButton.clicked.connect(
lambda: self.choose_file(self.stuGroup.setContent, "已选择文件:", lambda x: self.chooseSignal.emit('s', x)))
self.chooseQuestionButton.clicked.connect(
lambda: self.choose_file(self.QueGroup.setContent, "已选择文件:", lambda x: self.chooseSignal.emit('q', x)))
def choose_file(
self,
set_value: Callable[[str], None] = None,
prefix: str = "",
cb: Callable[[str], None] = None
) -> None:
file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Excel 文件 (*.xlsx *.xlsm);")
if file_path and set_value:
set_value(prefix + file_path)
if cb:
cb(file_path)
class ExportSettingsCard(GroupHeaderCardWidget):
startSignal = Signal()
updateSignal = Signal(str, str)
def __init__(self, parent=None):
super().__init__(parent)
self.setTitle("导出")
self.setBorderRadius(8)
self.chooseExportDirectoryButton = PushButton("选择")
self.exportFileNameLineEdit = LineEdit()
self.startButton = PrimaryPushButton(FluentIcon.PLAY_SOLID, "开始")
self.hintIcon = IconWidget(InfoBarIcon.INFORMATION)
self.hintLabel = BodyLabel("点击导出按钮以开始生成 👉")
self.chooseExportDirectoryButton.setFixedWidth(120)
self.startButton.setFixedWidth(120)
self.exportFileNameLineEdit.setFixedWidth(360)
self.exportFileNameLineEdit.setPlaceholderText("输入导出文件名例如21工程管理1答辩题目")
self.bottomLayout = QHBoxLayout()
self.startButton.setEnabled(False)
# 设置底部工具栏布局
self.hintIcon.setFixedSize(16, 16)
self.bottomLayout.setSpacing(10)
self.bottomLayout.setContentsMargins(24, 15, 24, 20)
self.bottomLayout.addWidget(self.hintIcon, 0, Qt.AlignLeft)
self.bottomLayout.addWidget(self.hintLabel, 0, Qt.AlignLeft)
self.bottomLayout.addStretch(1)
self.bottomLayout.addWidget(self.startButton, 0, Qt.AlignRight)
self.bottomLayout.setAlignment(Qt.AlignVCenter)
self.dirGroup = self.addGroup(FluentIcon.FOLDER, "导出目录", "选择导出文件的目录",
self.chooseExportDirectoryButton)
self.fnGroup = self.addGroup(FluentIcon.DOCUMENT, "导出文件名", "输入导出文件的名称",
self.exportFileNameLineEdit)
self.fnGroup.setSeparatorVisible(True)
self.vBoxLayout.addLayout(self.bottomLayout)
# ==============
self.chooseExportDirectoryButton.clicked.connect(self.choose_dir)
self.startButton.clicked.connect(self.startSignal.emit)
self.exportFileNameLineEdit.textChanged.connect(lambda x: self.updateSignal.emit('n', x))
def choose_dir(self) -> None:
dir_path = QFileDialog.getExistingDirectory(self, "选择文件夹", "")
if dir_path:
self.dirGroup.setContent(f"当前保存的文件目录:{dir_path}")
self.updateSignal.emit('d', dir_path)
def update_export_setting_by_signal(self, path: str) -> None:
f_dir = path[:path.rfind('/')]
f_name = path[path.rfind('/') + 1:path.rfind('.')]
self.dirGroup.setContent(f"当前保存的文件目录:{f_dir}")
self.updateSignal.emit('d', f_dir)
self.exportFileNameLineEdit.setText(f"{f_name}-答辩题目")
self.updateSignal.emit('n', f_name)
class DefenseWidget(Widget):
def __init__(self, key: str, parent=None):
super().__init__(key, parent)
self.initCard = InitSettingCard(self)
self.exportCard = ExportSettingsCard(self)
self.vbox = QVBoxLayout(self)
self.vbox.addWidget(self.initCard)
self.vbox.addWidget(self.exportCard)
self.vbox.addStretch(1)
self.infoBar = None
self.pb = None
self.thread = None
self.worker = None
# ===================================
self.input_student_filepath = None
self.input_question_filepath = None
self.output_filepath = None
self.output_filename = None
# ====================================
self.initCard.chooseSignal.connect(self.input_signal_receive)
self.exportCard.updateSignal.connect(self.export_update_signal_receive)
self.exportCard.startSignal.connect(self.start_generate)
def show_info_bar(self):
self.infoBar = InfoBar(
icon=InfoBarIcon.INFORMATION,
title='请稍后',
content="",
orient=Qt.Horizontal,
isClosable=False,
position=InfoBarPosition.BOTTOM,
duration=-1,
parent=self
)
self.pb = ProgressBar(self.infoBar)
self.infoBar.addWidget(self.pb)
self.infoBar.show()
def set_pb_value(self, value: int) -> None:
if self.pb:
self.pb.setValue(value)
if value == 100:
self.infoBar.close()
self.infoBar = InfoBar.success(
title='成功!',
content="正在打开文件...",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.BOTTOM,
duration=5000,
parent=self
)
self.pb = None
self.exportCard.startButton.setEnabled(True)
def enable_start_check(func: Callable):
@wraps(func)
def wrapper(self, *args, **kwargs):
result = func(self, *args, **kwargs)
fields = [
self.input_student_filepath,
self.input_question_filepath,
self.output_filepath,
self.output_filename
]
if all(fields):
self.exportCard.startButton.setEnabled(True)
else:
self.exportCard.startButton.setEnabled(False)
return result
return wrapper
@enable_start_check
def set_value(self, key: str, value: str) -> None:
if key == "input_student_filepath":
self.input_student_filepath = value
elif key == "input_question_filepath":
self.input_question_filepath = value
elif key == "output_filepath":
self.output_filepath = value
elif key == "output_filename":
self.output_filename = value
setattr(self, key, value)
def input_signal_receive(self, s_type: Literal['s', 'q'], value: str):
if s_type == "s":
self.set_value("input_student_filepath", value)
self.exportCard.update_export_setting_by_signal(value)
elif s_type == "q":
self.set_value("input_question_filepath", value)
def export_update_signal_receive(self, s_type: Literal['d', 'n'], value: str):
if s_type == "d":
self.set_value("output_filepath", value)
elif s_type == "n":
self.set_value("output_filename", value)
def start_generate(self):
self.thread = QThread()
self.worker = DTGWorker(
self.input_student_filepath,
self.input_question_filepath,
self.output_filepath,
self.output_filename
)
self.worker.moveToThread(self.thread)
self.show_info_bar()
self.exportCard.startButton.setEnabled(False)
# 线程启动与信号连接
self.thread.started.connect(self.worker.run)
self.worker.progress.connect(self.set_pb_value)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.thread.finished.connect(self.clear_thread_worker_refs)
# 启动线程
self.thread.start()
def clear_thread_worker_refs(self):
self.thread = None
self.worker = None