""" 点名组件 """ from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QRadioButton, QButtonGroup, QGroupBox, QSpinBox, QDoubleSpinBox, QCheckBox, QMessageBox, QTextEdit) from PyQt5.QtCore import Qt, QTimer from PyQt5.QtGui import QFont from frontend.utils.api_client import APIClient class RollCallWidget(QWidget): """点名界面""" def __init__(self, api_client: APIClient, parent=None): super().__init__(parent) self.api_client: APIClient = api_client self.current_student = None self.init_ui() def init_ui(self): """初始化界面""" layout = QVBoxLayout() # 标题 title = QLabel("课堂点名") title.setStyleSheet("font-size: 18px; font-weight: bold; margin: 10px;") title.setAlignment(Qt.AlignCenter) layout.addWidget(title) # 点名模式选择 mode_group = QGroupBox("点名模式") mode_layout = QHBoxLayout() self.mode_group = QButtonGroup() self.random_radio = QRadioButton("随机点名") self.random_radio.setChecked(True) self.mode_group.addButton(self.random_radio, 0) mode_layout.addWidget(self.random_radio) self.order_radio = QRadioButton("顺序点名") self.mode_group.addButton(self.order_radio, 1) mode_layout.addWidget(self.order_radio) mode_group.setLayout(mode_layout) layout.addWidget(mode_group) # 被点学生信息显示区域 info_group = QGroupBox("被点学生信息") info_layout = QVBoxLayout() self.student_info = QLabel("点击'开始点名'按钮开始") self.student_info.setAlignment(Qt.AlignCenter) self.student_info.setStyleSheet("font-size: 24px; font-weight: bold; padding: 20px;" "background-color: #f0f0f0; border-radius: 10px;") self.student_info.setMinimumHeight(150) info_layout.addWidget(self.student_info) info_group.setLayout(info_layout) layout.addWidget(info_group) # 点名按钮 button_layout = QHBoxLayout() self.start_btn = QPushButton("开始点名") self.start_btn.setStyleSheet("font-size: 16px; padding: 10px; background-color: #4CAF50; color: white;") self.start_btn.clicked.connect(self.start_rollcall) button_layout.addWidget(self.start_btn) layout.addLayout(button_layout) # 记录点名结果 record_group = QGroupBox("记录点名结果") record_layout = QVBoxLayout() # 到达情况 self.present_check = QCheckBox("学生已到达") self.present_check.setChecked(True) record_layout.addWidget(self.present_check) # 重复问题得分 repeat_layout = QHBoxLayout() repeat_layout.addWidget(QLabel("重复问题得分:")) self.repeat_score = QDoubleSpinBox() self.repeat_score.setRange(-1.0, 0.5) self.repeat_score.setSingleStep(0.5) self.repeat_score.setValue(0.0) self.repeat_score.setSuffix(" 分") repeat_layout.addWidget(self.repeat_score) repeat_layout.addWidget(QLabel("(-1:不能重复, 0:未测试, 0.5:准确重复)")) repeat_layout.addStretch() record_layout.addLayout(repeat_layout) # 回答问题得分 answer_layout = QHBoxLayout() answer_layout.addWidget(QLabel("回答问题得分:")) self.answer_score = QDoubleSpinBox() self.answer_score.setRange(0.0, 3.0) self.answer_score.setSingleStep(0.5) self.answer_score.setValue(0.0) self.answer_score.setSuffix(" 分") answer_layout.addWidget(self.answer_score) answer_layout.addWidget(QLabel("(0-3分,根据回答情况)")) answer_layout.addStretch() record_layout.addLayout(answer_layout) # 提交按钮 self.submit_btn = QPushButton("提交记录") self.submit_btn.setEnabled(False) self.submit_btn.clicked.connect(self.submit_record) record_layout.addWidget(self.submit_btn) record_group.setLayout(record_layout) layout.addWidget(record_group) # 最近点名记录 history_group = QGroupBox("最近点名记录") history_layout = QVBoxLayout() self.history_text = QTextEdit() self.history_text.setReadOnly(True) self.history_text.setMaximumHeight(150) history_layout.addWidget(self.history_text) history_group.setLayout(history_layout) layout.addWidget(history_group) layout.addStretch() self.setLayout(layout) def start_rollcall(self): """开始点名""" try: rollcall_type = "random" if self.random_radio.isChecked() else "order" result = self.api_client.start_rollcall(rollcall_type) self.current_student = result self.student_info.setText(f"学号: {result['student_code']}\n" f"姓名: {result['name']}\n" f"专业: {result.get('major', '')}\n" f"当前积分: {result['total_score']}") self.submit_btn.setEnabled(True) self.start_btn.setEnabled(False) # 重置表单 self.present_check.setChecked(True) self.repeat_score.setValue(0.0) self.answer_score.setValue(0.0) except Exception as e: QMessageBox.critical(self, "错误", f"点名失败: {str(e)}") def submit_record(self): """提交点名记录""" if not self.current_student: QMessageBox.warning(self, "提示", "请先开始点名") return try: record_data = { "student_id": self.current_student['student_id'], "rollcall_type": "random" if self.random_radio.isChecked() else "order", "is_present": self.present_check.isChecked(), "question_repeat_score": self.repeat_score.value(), "answer_score": self.answer_score.value() } result = self.api_client.record_rollcall(record_data) # 更新历史记录 history_text = (f"[{result['created_at']}] " f"{result['student_name']} ({result['student_code']}) - " f"积分变化: {result['total_score_change']:+.1f}\n") self.history_text.insertPlainText(history_text) QMessageBox.information(self, "成功", "点名记录已提交") # 重置状态 self.current_student = None self.submit_btn.setEnabled(False) self.start_btn.setEnabled(True) self.student_info.setText("点击'开始点名'按钮开始") except Exception as e: QMessageBox.critical(self, "错误", f"提交记录失败: {str(e)}")