You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
6.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
点名组件
"""
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)}")