完善提问模块

This commit is contained in:
2025-06-25 23:18:32 +08:00
parent 64f226c714
commit b845b5994a
6 changed files with 354 additions and 22 deletions

View File

@@ -1,27 +1,132 @@
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout
from qfluentwidgets import GroupHeaderCardWidget, PushButton, FluentIcon, PrimaryPushButton, IconWidget, BodyLabel
from PySide6.QtCore import Qt, Signal, QTimer
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget, QStackedWidget, QGridLayout, QFileDialog
from qfluentwidgets import GroupHeaderCardWidget, PushButton, FluentIcon, PrimaryPushButton, IconWidget, BodyLabel, \
SegmentedWidget, SpinBox, LargeTitleLabel, DisplayLabel, SubtitleLabel
from module.picker.schema import PickerExcel, PickerStudent
from ui.components.widget import RollingTextWidget
from ui import MAIN_THEME_COLOR
from ui.components.widget import Widget
from ui.components.window import MyWindow
class PickerWidget(Widget):
def __init__(self, key: str, parent=None):
super().__init__(key, parent)
class PSMMain(MyWindow):
finishSignal = Signal()
def __init__(self, student: PickerStudent, parent=None):
super().__init__(parent)
self.student = student
self.grade_edit = SpinBox(self)
self.init_layout()
def init_layout(self):
main_layout = QVBoxLayout()
hLayout = QHBoxLayout()
name_layout = QVBoxLayout()
date_layout = QVBoxLayout()
hLayout.addStretch()
hLayout.addLayout(name_layout)
hLayout.addLayout(date_layout)
hLayout.addStretch()
hLayout.setSpacing(20)
so = LargeTitleLabel(f"{self.student.so}", self)
so.setAlignment(Qt.AlignCenter)
sname = DisplayLabel(
f"{self.student.name[0] + ' ' + self.student.name[1] if len(self.student.name) == 2 else self.student.name}",
self)
sname.setAlignment(Qt.AlignCenter)
name_layout.addWidget(so)
name_layout.addWidget(sname)
self.grade_edit.setFixedWidth(260)
self.grade_edit.setRange(0, 100)
grade_layout = QHBoxLayout()
grade_layout.setContentsMargins(0, 0, 0, 48)
grade_layout.setSpacing(20)
submit_button = PrimaryPushButton("确定", self)
cancel_button = PushButton("重置", self)
submit_button.clicked.connect(self.close_modal)
cancel_button.clicked.connect(lambda: self.grade_edit.clear())
submit_button.setFixedWidth(120)
cancel_button.setFixedWidth(120)
grade_layout.addWidget(submit_button)
grade_layout.addWidget(cancel_button)
date_layout.addWidget(self.grade_edit)
date_layout.addLayout(grade_layout)
main_layout.addStretch()
main_layout.addLayout(hLayout)
main_layout.addStretch()
# 快速打分
quick_grade_layout = QVBoxLayout()
quick_grade_layout.setContentsMargins(0, 0, 0, 0)
quick_grade_layout.setSpacing(20)
quick_grade_title = SubtitleLabel("快速打分", self)
quick_grade_title.setAlignment(Qt.AlignCenter)
quick_grade_layout.addWidget(quick_grade_title)
grid_wrapper_layout = QHBoxLayout()
grid_layout = QGridLayout()
buttons = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
for i, num in enumerate(buttons):
row = i // 3
col = i % 3
btn = PushButton(str(num))
btn.setFixedSize(80, 80)
# 使用lambda绑定事件
btn.clicked.connect(lambda _, n=num: self.grade_edit.setValue(n))
grid_layout.addWidget(btn, row, col)
grid_wrapper_layout.addStretch()
grid_wrapper_layout.addLayout(grid_layout)
grid_wrapper_layout.addStretch()
quick_grade_layout.addLayout(grid_layout)
quick_grade_layout.addLayout(grid_wrapper_layout)
main_layout.addLayout(quick_grade_layout)
self.widgetLayout.addLayout(main_layout)
def close_modal(self):
self.student.append_score(self.grade_edit.value())
self.finishSignal.emit()
self.close()
class PickStudentMode(QWidget):
errorSignal = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.card = GroupHeaderCardWidget(self)
self.vbox = QVBoxLayout(self)
self.vbox.setContentsMargins(0, 0, 0, 0)
self.chooseBtn = PushButton("打开")
self.startButton = PrimaryPushButton(FluentIcon.PLAY_SOLID, "抽签")
self.startButton = PrimaryPushButton(FluentIcon.PLAY_SOLID, "开始")
self.bottomLayout = QHBoxLayout()
self.hintIcon = IconWidget(FluentIcon.INFO.icon(color=MAIN_THEME_COLOR))
self.hintLabel = BodyLabel("点击抽签按钮以开始抽签 👉")
self.hintLabel = BodyLabel("点击开始按钮以开始抽签 👉")
self.spinbox = SpinBox()
self.rollingText = RollingTextWidget(self)
self.card.setTitle("输入选项")
self.chooseBtn.setFixedWidth(120)
self.startButton.setFixedWidth(120)
self.startButton.setEnabled(False)
self.spinbox.setRange(0, 6)
self.spinbox.setFixedWidth(120)
self.spinbox.setEnabled(False)
self.hintIcon.setFixedSize(16, 16)
self.hintIcon.autoFillBackground()
@@ -33,9 +138,111 @@ class PickerWidget(Widget):
self.bottomLayout.addWidget(self.startButton, 0, Qt.AlignRight)
self.bottomLayout.setAlignment(Qt.AlignVCenter)
self.group = self.card.addGroup(FluentIcon.DOCUMENT, "抽答名单", "选择抽答名单", self.chooseBtn)
self.group.setSeparatorVisible(True)
self.group = self.card.addGroup(FluentIcon.DOCUMENT, "提问名单", "选择提问名单", self.chooseBtn)
self.spinGroup = self.card.addGroup(FluentIcon.SETTING, "提问次数", "设置提问的最大次数", self.spinbox)
self.spinGroup.setSeparatorVisible(True)
self.card.vBoxLayout.addLayout(self.bottomLayout)
self.vbox.addWidget(self.card)
self.vbox.addWidget(self.rollingText)
self.vbox.addStretch(1)
# ==============================
self.chooseBtn.clicked.connect(self.choose_file)
self.spinbox.valueChanged.connect(lambda: PickerExcel.save_total_time(value=self.spinbox.value()))
self.startButton.clicked.connect(self.start_rolling)
self.rollingText.finishSignal.connect(self.finish_rolling)
# ==============================
self.filepath = ""
self.students = []
def choose_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Excel 文件 (*.xlsm);")
if file_path:
self.group.setContent("已选择文件:" + file_path)
self.filepath = file_path
self.startButton.setEnabled(True)
self.init_spinbox_value()
def init_spinbox_value(self):
if not self.filepath:
return
try:
PickerExcel.open(self.filepath)
self.spinbox.setValue(PickerExcel.read_total_time())
self.spinbox.setEnabled(True)
except Exception as e:
self.errorSignal.emit(str(e))
self.spinbox.setEnabled(False)
self.startButton.setEnabled(False)
def start_rolling(self):
self.students = PickerExcel.read_student()
self.rollingText.set_items(self.students)
self.rollingText.start_rolling()
self.startButton.setEnabled(False)
def finish_rolling(self):
stu = PickerStudent.pick(self.students)
if not (stu.so and stu.name):
self.errorSignal.emit("学生信息读取失败")
self.rollingText.label.setText(stu.name)
timer = QTimer(self)
timer.setSingleShot(True)
timer.timeout.connect(lambda: self.show_screen(stu))
timer.timeout.connect(lambda: self.startButton.setEnabled(True))
timer.start(1000)
def show_screen(self, stu: PickerStudent):
screen = PSMMain(stu)
screen.finishSignal.connect(lambda: PickerExcel.write_back(stu))
screen.finishSignal.connect(lambda: self.rollingText.label.clear())
class PickQuestionMode(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
lable = DisplayLabel('🚧', self)
lable.setAlignment(Qt.AlignCenter)
self.layout = QHBoxLayout(self)
self.layout.addStretch()
self.layout.addWidget(lable)
self.layout.addStretch()
class PickerWidget(Widget):
errorSignal = Signal(str, str)
def __init__(self, key: str, parent=None):
super().__init__(key, parent)
self.vbox = QVBoxLayout(self)
self.menu = SegmentedWidget(self)
self.stack = QStackedWidget(self)
self.psm = PickStudentMode(self)
self.pqm = PickQuestionMode(self)
self.add_sub_interface(self.psm, "pickStudentMode", "选人模式")
self.add_sub_interface(self.pqm, "pickQuestionMode", "选题模式")
self.menu.setCurrentItem("pickStudentMode")
self.vbox.addWidget(self.menu)
self.vbox.addWidget(self.stack)
self.vbox.addStretch(1)
# ===========================
self.stack.currentChanged.connect(self.on_stack_index_changed)
self.psm.errorSignal.connect(lambda n: self.errorSignal.emit("😢 不好出错了", n))
def add_sub_interface(self, widget: QWidget, obj_name: str, text: str):
widget.setObjectName(obj_name)
self.stack.addWidget(widget)
self.menu.addItem(routeKey=obj_name, text=text, onClick=lambda: self.stack.setCurrentWidget(widget))
def on_stack_index_changed(self, index: int):
widget = self.stack.widget(index)
self.stack.setCurrentWidget(widget)