|
|
|
|
@ -0,0 +1,592 @@
|
|
|
|
|
|
|
|
|
|
# 课堂随机点名系统技术实现方案
|
|
|
|
|
|
|
|
|
|
**文件名:** 课堂随机点名系统_技术实现方案.md
|
|
|
|
|
|
|
|
|
|
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 10px; color: white; margin: 20px 0;">
|
|
|
|
|
<h1 style="color: white; text-align: center; margin: 0; font-size: 2.5em;">课堂随机点名系统技术实现方案</h1>
|
|
|
|
|
<p style="color: white; text-align: center; margin: 10px 0 0 0; font-size: 1.2em;">基于Python Tkinter的桌面应用开发方案</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
| 文档版本 | 编写日期 |
|
|
|
|
|
|---------|----------|
|
|
|
|
|
| v1.0 | 2025年11月22日 |
|
|
|
|
|
|
|
|
|
|
## 1. 技术栈选择说明
|
|
|
|
|
|
|
|
|
|
<div style="background-color: #e8f4fd; border-left: 4px solid #007bff; padding: 20px; margin: 20px 0; border-radius: 8px;">
|
|
|
|
|
<h3 style="color: #0056b3; margin-top: 0;">💡 技术选型决策依据</h3>
|
|
|
|
|
<p style="color: #333;">基于教育场景的特殊需求,选择Python + Tkinter技术栈具备明显的优势对比</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
### 1.1 Python + Tkinter技术优势分析
|
|
|
|
|
|
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 25px 0;">
|
|
|
|
|
<div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
|
|
|
|
|
<h4 style="color: #007bff; margin-top: 0;">🎯 开发效率优势</h4>
|
|
|
|
|
<ul>
|
|
|
|
|
<li style="color: #333;">Python语法简洁,开发周期缩短40%</li>
|
|
|
|
|
<li style="color: #333;">丰富的第三方库支持数据操作</li>
|
|
|
|
|
<li style="color: #333;">快速原型验证和迭代开发</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
|
|
|
|
|
<h4 style="color: #28a745; margin-top: 0;">💻 部署便捷性</h4>
|
|
|
|
|
<ul>
|
|
|
|
|
<li style="color: #333;">跨平台兼容(Windows/macOS/Linux)</li>
|
|
|
|
|
<li style="color: #333;">无需复杂环境配置</li>
|
|
|
|
|
<li style="color: #333;">单文件打包分发</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
|
|
|
|
|
<h4 style="color: #dc3545; margin-top: 0;">📊 教育场景适配</h4>
|
|
|
|
|
<ul>
|
|
|
|
|
<li style="color: #333;">教育资源丰富,易于教学维护</li>
|
|
|
|
|
<li style="color: #333;">教师友好型界面设计</li>
|
|
|
|
|
<li style="color: #333;">离线使用能力保障</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
### 1.2 技术栈对比分析
|
|
|
|
|
|
|
|
|
|
<div style="overflow-x: auto; margin: 20px 0;">
|
|
|
|
|
|
|
|
|
|
| 技术方案 | 开发难度 | 部署复杂度 | 性能表现 | 扩展性 | 维护成本 |
|
|
|
|
|
|---------|---------|-----------|---------|--------|---------|
|
|
|
|
|
| <span style="color: #007bff; font-weight: bold;">Python + Tkinter</span> | <span style="color: #28a745;">低</span> | <span style="color: #28a745;">低</span> | <span style="color: #ffc107;">中等</span> | <span style="color: #28a745;">高</span> | <span style="color: #28a745;">低</span> |
|
|
|
|
|
| Web方案(HTML+JS) | <span style="color: #ffc107;">中等</span> | <span style="color: #dc3545;">高</span> | <span style="color: #28a745;">高</span> | <span style="color: #28a745;">高</span> | <span style="color: #ffc107;">中等</span> |
|
|
|
|
|
| C# WinForms | <span style="color: #ffc107;">中等</span> | <span style="color: #ffc107;">中等</span> | <span style="color: #28a745;">高</span> | <span style="color: #ffc107;">中等</span> | <span style="color: #ffc107;">中等</span> |
|
|
|
|
|
| Java Swing | <span style="color: #dc3545;">高</span> | <span style="color: #dc3545;">高</span> | <span style="color: #28a745;">高</span> | <span style="color: #28a745;">高</span> | <span style="color: #dc3545;">高</span> |
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
### 1.3 核心依赖库选择
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
# 核心依赖库配置
|
|
|
|
|
required_libraries = {
|
|
|
|
|
"tkinter": "内置GUI框架",
|
|
|
|
|
"sqlite3": "内置轻量级数据库",
|
|
|
|
|
"pandas": "Excel文件处理和数据操作",
|
|
|
|
|
"openpyxl": "Excel文件读写支持",
|
|
|
|
|
"datetime": "日期时间处理",
|
|
|
|
|
"random": "随机算法实现",
|
|
|
|
|
"json": "配置文件处理"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 15px 0; border-radius: 5px;">
|
|
|
|
|
<strong style="color: #856404;">⚠️ 注意事项:</strong><span style="color: #856404;"> 优先使用Python内置库,减少外部依赖,确保部署稳定性</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
## 2. 核心模块功能实现方案
|
|
|
|
|
|
|
|
|
|
### 2.1 系统架构设计
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
graph TB
|
|
|
|
|
A[用户界面层] --> B[业务逻辑层]
|
|
|
|
|
B --> C[数据访问层]
|
|
|
|
|
|
|
|
|
|
A1[主窗口Manager] --> A2[界面组件]
|
|
|
|
|
A2 --> A3[事件处理]
|
|
|
|
|
|
|
|
|
|
B1[点名引擎] --> B2[学生管理]
|
|
|
|
|
B2 --> B3[历史记录]
|
|
|
|
|
B3 --> B4[统计计算]
|
|
|
|
|
|
|
|
|
|
C1[SQLite数据库] --> C2[Excel文件]
|
|
|
|
|
C2 --> C3[配置文件]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2.2 点名引擎模块实现
|
|
|
|
|
|
|
|
|
|
<div style="background-color: #f8f9fa; border-left: 4px solid #6f42c1; padding: 20px; margin: 20px 0; border-radius: 8px;">
|
|
|
|
|
<h4 style="color: #6f42c1; margin-top: 0;">🎲 随机算法核心实现</h4>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
class RandomSelector:
|
|
|
|
|
def __init__(self, student_list):
|
|
|
|
|
self.students = student_list
|
|
|
|
|
self.selected_history = []
|
|
|
|
|
|
|
|
|
|
def weighted_random_selection(self):
|
|
|
|
|
"""加权随机选择算法,优先选择未点到学生"""
|
|
|
|
|
if not self.students:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
# 计算权重:未点到学生权重高,已点到学生权重低
|
|
|
|
|
weights = []
|
|
|
|
|
for student in self.students:
|
|
|
|
|
point_count = self.get_recent_point_count(student.id)
|
|
|
|
|
weight = max(1, 10 - point_count) # 最近点到次数越少,权重越高
|
|
|
|
|
weights.append(weight)
|
|
|
|
|
|
|
|
|
|
total_weight = sum(weights)
|
|
|
|
|
if total_weight == 0:
|
|
|
|
|
return random.choice(self.students)
|
|
|
|
|
|
|
|
|
|
# 执行加权随机选择
|
|
|
|
|
rand_val = random.uniform(0, total_weight)
|
|
|
|
|
cumulative = 0
|
|
|
|
|
for i, weight in enumerate(weights):
|
|
|
|
|
cumulative += weight
|
|
|
|
|
if rand_val <= cumulative:
|
|
|
|
|
return self.students[i]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2.3 动画效果实现方案
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
class AnimationManager:
|
|
|
|
|
def __init__(self, canvas_widget):
|
|
|
|
|
self.canvas = canvas_widget
|
|
|
|
|
self.animation_id = None
|
|
|
|
|
self.is_animating = False
|
|
|
|
|
|
|
|
|
|
def start_roll_animation(self, duration=3000):
|
|
|
|
|
"""开始滚动动画效果"""
|
|
|
|
|
self.is_animating = True
|
|
|
|
|
self.animation_start_time = time.time()
|
|
|
|
|
self.animate_roll()
|
|
|
|
|
|
|
|
|
|
def animate_roll(self):
|
|
|
|
|
if not self.is_animating:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
elapsed = time.time() - self.animation_start_time
|
|
|
|
|
progress = min(elapsed / 3.0, 1.0) # 3秒动画周期
|
|
|
|
|
|
|
|
|
|
# 计算当前显示的学生索引(非线性缓动效果)
|
|
|
|
|
current_index = self.calculate_current_index(progress)
|
|
|
|
|
self.display_student(current_index)
|
|
|
|
|
|
|
|
|
|
if progress < 1.0:
|
|
|
|
|
# 继续动画,使用缓动函数调整速度
|
|
|
|
|
interval = self.calculate_interval(progress)
|
|
|
|
|
self.canvas.after(int(interval * 1000), self.animate_roll)
|
|
|
|
|
else:
|
|
|
|
|
self.finalize_selection()
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2.4 文件导入模块实现
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
class ExcelImporter:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.supported_formats = ['.xlsx', '.xls', '.csv']
|
|
|
|
|
|
|
|
|
|
def import_students(self, file_path):
|
|
|
|
|
"""导入Excel文件并解析学生数据"""
|
|
|
|
|
try:
|
|
|
|
|
if file_path.endswith('.csv'):
|
|
|
|
|
df = pd.read_csv(file_path)
|
|
|
|
|
else:
|
|
|
|
|
df = pd.read_excel(file_path, engine='openpyxl')
|
|
|
|
|
|
|
|
|
|
students = []
|
|
|
|
|
required_columns = ['学号', '姓名', '班级']
|
|
|
|
|
|
|
|
|
|
# 验证文件格式
|
|
|
|
|
if not all(col in df.columns for col in required_columns):
|
|
|
|
|
raise ValueError("文件格式错误:缺少必要列")
|
|
|
|
|
|
|
|
|
|
for _, row in df.iterrows():
|
|
|
|
|
student = Student(
|
|
|
|
|
id=str(row['学号']),
|
|
|
|
|
name=str(row['姓名']),
|
|
|
|
|
class_name=str(row['班级'])
|
|
|
|
|
)
|
|
|
|
|
students.append(student)
|
|
|
|
|
|
|
|
|
|
return students
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise Exception(f"文件导入失败:{str(e)}")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 3. 数据库设计
|
|
|
|
|
|
|
|
|
|
### 3.1 数据库架构设计
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
erDiagram
|
|
|
|
|
STUDENT ||--o{ POINT_HISTORY : has
|
|
|
|
|
STUDENT {
|
|
|
|
|
string student_id PK "学号"
|
|
|
|
|
string name "姓名"
|
|
|
|
|
string class_name "班级"
|
|
|
|
|
datetime created_at "创建时间"
|
|
|
|
|
datetime updated_at "更新时间"
|
|
|
|
|
}
|
|
|
|
|
POINT_HISTORY {
|
|
|
|
|
int history_id PK "记录ID"
|
|
|
|
|
string student_id FK "学号"
|
|
|
|
|
datetime point_time "点名时间"
|
|
|
|
|
string point_type "点名类型"
|
|
|
|
|
string note "备注"
|
|
|
|
|
}
|
|
|
|
|
SYSTEM_CONFIG {
|
|
|
|
|
string config_key PK "配置键"
|
|
|
|
|
string config_value "配置值"
|
|
|
|
|
datetime updated_at "更新时间"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 3.2 数据表详细设计
|
|
|
|
|
|
|
|
|
|
<div style="overflow-x: auto; margin: 20px 0;">
|
|
|
|
|
|
|
|
|
|
| 表名 | 字段名 | 数据类型 | 约束 | 说明 |
|
|
|
|
|
|------|--------|---------|------|------|
|
|
|
|
|
| **students** | student_id | VARCHAR(20) | PRIMARY KEY | 学生学号 |
|
|
|
|
|
| | name | VARCHAR(50) | NOT NULL | 学生姓名 |
|
|
|
|
|
| | class_name | VARCHAR(50) | NOT NULL | 班级名称 |
|
|
|
|
|
| | created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
|
|
|
|
|
| | updated_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
|
|
|
|
|
| **point_history** | history_id | INTEGER | PRIMARY KEY AUTOINCREMENT | 记录ID |
|
|
|
|
|
| | student_id | VARCHAR(20) | FOREIGN KEY | 学生学号 |
|
|
|
|
|
| | point_time | DATETIME | NOT NULL | 点名时间 |
|
|
|
|
|
| | point_type | VARCHAR(20) | DEFAULT 'normal' | 点名类型 |
|
|
|
|
|
| | note | TEXT | | 备注信息 |
|
|
|
|
|
| **system_config** | config_key | VARCHAR(50) | PRIMARY KEY | 配置键 |
|
|
|
|
|
| | config_value | TEXT | | 配置值 |
|
|
|
|
|
| | updated_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
### 3.3 数据库操作封装
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
class DatabaseManager:
|
|
|
|
|
def __init__(self, db_path="classroom_points.db"):
|
|
|
|
|
self.db_path = db_path
|
|
|
|
|
self.init_database()
|
|
|
|
|
|
|
|
|
|
def init_database(self):
|
|
|
|
|
"""初始化数据库表结构"""
|
|
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
|
|
|
|
# 创建学生表
|
|
|
|
|
cursor.execute('''
|
|
|
|
|
CREATE TABLE IF NOT EXISTS students (
|
|
|
|
|
student_id VARCHAR(20) PRIMARY KEY,
|
|
|
|
|
name VARCHAR(50) NOT NULL,
|
|
|
|
|
class_name VARCHAR(50) NOT NULL,
|
|
|
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
|
|
|
)
|
|
|
|
|
''')
|
|
|
|
|
|
|
|
|
|
# 创建点名历史表
|
|
|
|
|
cursor.execute('''
|
|
|
|
|
CREATE TABLE IF NOT EXISTS point_history (
|
|
|
|
|
history_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
student_id VARCHAR(20),
|
|
|
|
|
point_time DATETIME NOT NULL,
|
|
|
|
|
point_type VARCHAR(20) DEFAULT 'normal',
|
|
|
|
|
note TEXT,
|
|
|
|
|
FOREIGN KEY (student_id) REFERENCES students (student_id)
|
|
|
|
|
)
|
|
|
|
|
''')
|
|
|
|
|
|
|
|
|
|
conn.commit()
|
|
|
|
|
conn.close()
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 4. 界面开发指南
|
|
|
|
|
|
|
|
|
|
### 4.1 主界面布局实现
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
class MainApplication:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.root = tk.Tk()
|
|
|
|
|
self.root.title("课堂点名系统")
|
|
|
|
|
self.root.geometry("1200x800")
|
|
|
|
|
self.root.configure(bg="#ECF0F1")
|
|
|
|
|
|
|
|
|
|
self.setup_layout()
|
|
|
|
|
self.create_widgets()
|
|
|
|
|
|
|
|
|
|
def setup_layout(self):
|
|
|
|
|
"""设置主界面布局结构"""
|
|
|
|
|
# 顶部功能区
|
|
|
|
|
self.top_frame = tk.Frame(self.root, height=80, bg="#3498DB")
|
|
|
|
|
self.top_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
|
|
|
|
|
|
|
|
# 主内容区
|
|
|
|
|
self.main_frame = tk.Frame(self.root, bg="white")
|
|
|
|
|
self.main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
|
|
|
|
|
|
|
|
|
|
# 底部状态栏
|
|
|
|
|
self.status_frame = tk.Frame(self.root, height=40, bg="#2C3E50")
|
|
|
|
|
self.status_frame.pack(fill=tk.X, side=tk.BOTTOM)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.2 组件样式定制
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
def setup_styles(self):
|
|
|
|
|
"""配置Tkinter样式"""
|
|
|
|
|
style = ttk.Style()
|
|
|
|
|
|
|
|
|
|
# 配置主按钮样式
|
|
|
|
|
style.configure('Primary.TButton',
|
|
|
|
|
background='#3498DB',
|
|
|
|
|
foreground='white',
|
|
|
|
|
font=('微软雅黑', 11, 'bold'),
|
|
|
|
|
padding=(20, 10))
|
|
|
|
|
|
|
|
|
|
# 配置表格样式
|
|
|
|
|
style.configure('Treeview',
|
|
|
|
|
font=('微软雅黑', 10),
|
|
|
|
|
rowheight=25)
|
|
|
|
|
style.configure('Treeview.Heading',
|
|
|
|
|
font=('微软雅黑', 11, 'bold'))
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.3 响应式布局适配
|
|
|
|
|
|
|
|
|
|
<div style="background-color: #d4edda; border-left: 4px solid #28a745; padding: 15px; margin: 15px 0; border-radius: 5px;">
|
|
|
|
|
<strong style="color: #155724;">✅ 最佳实践:</strong><span style="color: #155724;"> 使用Grid布局管理器实现灵活的响应式设计</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
def create_responsive_layout(self):
|
|
|
|
|
"""创建响应式布局"""
|
|
|
|
|
# 左侧导航区
|
|
|
|
|
self.nav_frame = tk.Frame(self.main_frame, width=250, bg="#F8F9FA")
|
|
|
|
|
self.nav_frame.grid(row=0, column=0, rowspan=2, sticky="nswe", padx=(0, 10))
|
|
|
|
|
|
|
|
|
|
# 中央内容区
|
|
|
|
|
self.content_frame = tk.Frame(self.main_frame, bg="white")
|
|
|
|
|
self.content_frame.grid(row=0, column=1, sticky="nswe")
|
|
|
|
|
|
|
|
|
|
# 右侧统计区
|
|
|
|
|
self.stats_frame = tk.Frame(self.main_frame, width=200, bg="#F8F9FA")
|
|
|
|
|
self.stats_frame.grid(row=0, column=2, rowspan=2, sticky="nswe", padx=(10, 0))
|
|
|
|
|
|
|
|
|
|
# 配置权重使中央区域可伸缩
|
|
|
|
|
self.main_frame.grid_columnconfigure(1, weight=1)
|
|
|
|
|
self.main_frame.grid_rowconfigure(0, weight=1)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 5. 部署和运行说明
|
|
|
|
|
|
|
|
|
|
### 5.1 环境要求与依赖安装
|
|
|
|
|
|
|
|
|
|
<div style="overflow-x: auto; margin: 20px 0;">
|
|
|
|
|
|
|
|
|
|
| 环境组件 | 版本要求 | 安装方法 | 验证命令 |
|
|
|
|
|
|---------|---------|---------|---------|
|
|
|
|
|
| Python | 3.8+ | 官网下载安装 | `python --version` |
|
|
|
|
|
| pandas | 1.5.0+ | `pip install pandas` | `python -c "import pandas; print(pandas.__version__)"` |
|
|
|
|
|
| openpyxl | 3.0.0+ | `pip install openpyxl` | `python -c "import openpyxl; print(openpyxl.__version__)"` |
|
|
|
|
|
| 操作系统 | Win7+/macOS 10.12+/Ubuntu 16.04+ | - | - |
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
### 5.2 项目目录结构
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
课堂点名系统/
|
|
|
|
|
├── main.py # 主程序入口
|
|
|
|
|
├── requirements.txt # 依赖包列表
|
|
|
|
|
├── config/
|
|
|
|
|
│ ├── settings.json # 配置文件
|
|
|
|
|
│ └── database.db # SQLite数据库
|
|
|
|
|
├── src/
|
|
|
|
|
│ ├── gui/ # 界面模块
|
|
|
|
|
│ │ ├── main_window.py # 主窗口
|
|
|
|
|
│ │ ├── components.py # 组件类
|
|
|
|
|
│ │ └── styles.py # 样式定义
|
|
|
|
|
│ ├── core/ # 核心逻辑
|
|
|
|
|
│ │ ├── random_selector.py # 随机算法
|
|
|
|
|
│ │ ├── data_manager.py # 数据管理
|
|
|
|
|
│ │ └── animation_engine.py # 动画引擎
|
|
|
|
|
│ └── utils/ # 工具类
|
|
|
|
|
│ ├── file_importer.py # 文件导入
|
|
|
|
|
│ ├── database.py # 数据库操作
|
|
|
|
|
│ └── helpers.py # 辅助函数
|
|
|
|
|
├── assets/ # 资源文件
|
|
|
|
|
│ ├── icons/ # 图标资源
|
|
|
|
|
│ └── templates/ # Excel模板
|
|
|
|
|
└── docs/ # 文档
|
|
|
|
|
└── 使用说明.md # 用户手册
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 5.3 打包发布方案
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
# pyinstaller打包配置(spec文件)
|
|
|
|
|
# classroom_points.spec
|
|
|
|
|
|
|
|
|
|
block_cipher = None
|
|
|
|
|
|
|
|
|
|
a = Analysis(
|
|
|
|
|
['main.py'],
|
|
|
|
|
pathex=[],
|
|
|
|
|
binaries=[],
|
|
|
|
|
datas=[
|
|
|
|
|
('assets/', 'assets/'),
|
|
|
|
|
('config/', 'config/')
|
|
|
|
|
],
|
|
|
|
|
hiddenimports=[],
|
|
|
|
|
hookspath=[],
|
|
|
|
|
hooksconfig={},
|
|
|
|
|
runtime_hooks=[],
|
|
|
|
|
excludes=[],
|
|
|
|
|
win_no_prefer_redirects=False,
|
|
|
|
|
win_private_assemblies=False,
|
|
|
|
|
cipher=block_cipher,
|
|
|
|
|
noarchive=False,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
|
|
|
|
|
|
|
|
exe = EXE(
|
|
|
|
|
pyz,
|
|
|
|
|
a.scripts,
|
|
|
|
|
a.binaries,
|
|
|
|
|
a.zipfiles,
|
|
|
|
|
a.datas,
|
|
|
|
|
[],
|
|
|
|
|
name='课堂点名系统',
|
|
|
|
|
debug=False,
|
|
|
|
|
bootloader_ignore_signals=False,
|
|
|
|
|
strip=False,
|
|
|
|
|
upx=True,
|
|
|
|
|
upx_exclude=[],
|
|
|
|
|
runtime_tmpdir=None,
|
|
|
|
|
console=False, # 设置为True可显示控制台窗口
|
|
|
|
|
icon='assets/icon.ico'
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 5.4 部署操作指南
|
|
|
|
|
|
|
|
|
|
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 15px 0; border-radius: 5px;">
|
|
|
|
|
<strong style="color: #856404;">📋 部署步骤:</strong><span style="color: #856404;"> 按照以下步骤完成系统部署</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
**步骤1:环境准备**
|
|
|
|
|
```bash
|
|
|
|
|
# 1. 安装Python 3.8或更高版本
|
|
|
|
|
# 2. 下载项目代码
|
|
|
|
|
git clone <项目仓库>
|
|
|
|
|
cd 课堂点名系统
|
|
|
|
|
|
|
|
|
|
# 3. 安装依赖
|
|
|
|
|
pip install -r requirements.txt
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**步骤2:首次运行配置**
|
|
|
|
|
```bash
|
|
|
|
|
# 1. 运行主程序
|
|
|
|
|
python main.py
|
|
|
|
|
|
|
|
|
|
# 2. 系统将自动创建配置文件和数据文件
|
|
|
|
|
# 3. 根据需要调整系统设置
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**步骤3:打包分发(可选)**
|
|
|
|
|
```bash
|
|
|
|
|
# 使用PyInstaller打包为可执行文件
|
|
|
|
|
pip install pyinstaller
|
|
|
|
|
pyinstaller classroom_points.spec
|
|
|
|
|
|
|
|
|
|
# 生成的exe文件在dist目录下
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 5.5 故障排除指南
|
|
|
|
|
|
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 25px 0;">
|
|
|
|
|
<div style="background: #f8d7da; padding: 15px; border-radius: 8px;">
|
|
|
|
|
<h4 style="color: #721c24; margin-top: 0;">❌ 常见问题1:依赖包安装失败</h4>
|
|
|
|
|
<p style="color: #721c24;"><strong>解决方案:</strong>使用国内镜像源安装<br>pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="background: #d1ecf1; padding: 15px; border-radius: 8px;">
|
|
|
|
|
<h4 style="color: #0c5460; margin-top: 0;">❌ 常见问题2:Excel导入失败</h4>
|
|
|
|
|
<p style="color: #0c5460;"><strong>解决方案:</strong>检查Excel文件格式,确保包含学号、姓名、班级三列</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="background: #ffeaa7; padding: 15px; border-radius: 8px;">
|
|
|
|
|
<h4 style="color: #856404; margin-top: 0;">❌ 常见问题3:界面显示异常</h4>
|
|
|
|
|
<p style="color: #856404;"><strong>解决方案:</strong>调整系统DPI设置或使用兼容模式运行</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
## 6. 性能优化建议
|
|
|
|
|
|
|
|
|
|
### 6.1 数据库性能优化
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
def optimize_database_performance(self):
|
|
|
|
|
"""数据库性能优化配置"""
|
|
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
|
|
|
|
# 启用WAL模式提高并发性能
|
|
|
|
|
cursor.execute("PRAGMA journal_mode=WAL")
|
|
|
|
|
|
|
|
|
|
# 设置合适的缓存大小
|
|
|
|
|
cursor.execute("PRAGMA cache_size=-64000") # 64MB缓存
|
|
|
|
|
|
|
|
|
|
# 创建索引提升查询性能
|
|
|
|
|
cursor.execute("CREATE INDEX IF NOT EXISTS idx_student_class ON students(class_name)")
|
|
|
|
|
cursor.execute("CREATE INDEX IF NOT EXISTS idx_history_time ON point_history(point_time)")
|
|
|
|
|
cursor.execute("CREATE INDEX IF NOT EXISTS idx_history_student ON point_history(student_id)")
|
|
|
|
|
|
|
|
|
|
conn.commit()
|
|
|
|
|
conn.close()
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 6.2 内存管理优化
|
|
|
|
|
|
|
|
|
|
<div style="background-color: #e8f4fd; border-left: 4px solid #007bff; padding: 20px; margin: 20px 0; border-radius: 8px;">
|
|
|
|
|
<h4 style="color: #0056b3; margin-top: 0;">💡 内存优化策略</h4>
|
|
|
|
|
<ul>
|
|
|
|
|
<li style="color: #333;">使用分页加载大量学生数据</li>
|
|
|
|
|
<li style="color: #333;">及时释放不再使用的界面组件</li>
|
|
|
|
|
<li style="color: #333;">优化图片和资源文件加载</li>
|
|
|
|
|
<li style="color: #333;">定期清理临时数据</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
## 7. 安全与稳定性保障
|
|
|
|
|
|
|
|
|
|
### 7.1 数据安全措施
|
|
|
|
|
|
|
|
|
|
- **数据备份机制**:自动定期备份数据库文件
|
|
|
|
|
- **输入验证**:对所有用户输入进行严格验证
|
|
|
|
|
- **异常处理**:完善的异常捕获和处理机制
|
|
|
|
|
- **日志记录**:详细的操作日志记录系统
|
|
|
|
|
|
|
|
|
|
### 7.2 系统稳定性策略
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
def setup_error_handling(self):
|
|
|
|
|
"""设置全局异常处理"""
|
|
|
|
|
def global_exception_handler(exc_type, exc_value, exc_traceback):
|
|
|
|
|
if issubclass(exc_type, KeyboardInterrupt):
|
|
|
|
|
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
logger.error("未捕获的异常:", exc_info=(exc_type, exc_value, exc_traceback))
|
|
|
|
|
|
|
|
|
|
# 显示用户友好的错误信息
|
|
|
|
|
messagebox.showerror(
|
|
|
|
|
"系统错误",
|
|
|
|
|
"发生意外错误,程序将继续运行。\n错误信息已记录到日志。"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
sys.excepthook = global_exception_handler
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
**文档完成时间:2025年11月22日**
|
|
|
|
|
"# class-call-system"
|