当前位置:首页>python>【一周精选】Python可视化实战:从零打造高颜值学生成绩管理系统

【一周精选】Python可视化实战:从零打造高颜值学生成绩管理系统

  • 2026-04-13 11:57:27
【一周精选】Python可视化实战:从零打造高颜值学生成绩管理系统

🔥PyQt5+数据库+图表全能实现!

在数字化教学管理的当下,一款简洁、高效、美观的学生成绩管理工具,能让教师和管理员告别繁琐的表格统计,轻松完成学生信息管理、成绩分析、数据导出导入等工作。作为Python开发者,我们完全可以用PyQt5图形化界面+SQLite轻量数据库+Matplotlib可视化图表,打造一款功能齐全、界面精致、权限分明的桌面级管理系统——无需复杂配置,本地即可运行,兼顾实用性与高级感,无论是教学实训、班级管理还是个人项目开发,都是绝佳的实战案例!

很多新手会觉得GUI开发、数据库操作、数据可视化是三个独立的难点,但今天这套系统将三者完美融合:界面设计遵循美观大方的原则,不透明质感搭配规整布局,视觉效果超好看;功能上覆盖登录验证、学生/班级/教师全维度管理、Excel批量导入导出、成绩柱状图统计,还实现了管理员与教师的权限区分;代码结构清晰模块化,零基础也能看懂、能修改、能拓展。接下来我就带大家拆解核心代码,手把手带你实现这款全能成绩管理系统,看完就能直接上手用!

✨一、核心模块一:数据库初始化设计

任何管理系统都离不开数据存储,我们选用SQLite嵌入式数据库,无需单独安装服务,生成本地.db文件即可存储所有数据,轻量化且适配桌面程序。这个模块的核心作用是自动创建数据表、初始化超级管理员,程序启动时自动执行,无需手动建库,极大降低使用成本。

我们设计了4张核心数据表:

  1. user用户表:存储管理员、教师账号密码、角色、绑定班级,实现权限区分
  2. class班级表:存储班级信息,关联学生与教师
  3. student学生表:核心数据表,存储学号、姓名、性别、班级、三科成绩
  4. 自动初始化默认管理员账号:admin/123456,登录即可使用全部功能

完整代码

# ===================== 1. 数据库初始化 =====================definit_db():# 连接本地数据库,不存在则自动创建    conn = sqlite3.connect("score_db.db")    c = conn.cursor()# 用户表(管理员/教师):存储账号、密码、角色、绑定班级    c.execute('''CREATE TABLE IF NOT EXISTS user                 (id INTEGER PRIMARY KEY AUTOINCREMENT,                  username TEXT UNIQUE,                  password TEXT,                  role TEXT,  -- admin=管理员/teacher=教师                  class_id INTEGER)''')# 班级表:存储班级名称    c.execute('''CREATE TABLE IF NOT EXISTS class                 (id INTEGER PRIMARY KEY AUTOINCREMENT,                  class_name TEXT UNIQUE)''')# 学生表:核心成绩数据    c.execute('''CREATE TABLE IF NOT EXISTS student                 (id INTEGER PRIMARY KEY AUTOINCREMENT,                  stu_id TEXT UNIQUE,  # 学号唯一                  name TEXT,                  gender TEXT,                  class_id INTEGER,                  chinese INTEGER,                  math INTEGER,                  english INTEGER)''')# 初始化超级管理员:若不存在则创建默认账号    c.execute("SELECT * FROM user WHERE username='admin'")ifnot c.fetchone():        c.execute("INSERT INTO user(username,password,role) VALUES ('admin','123456','admin')")# 提交事务并关闭连接    conn.commit()    conn.close()

代码详解

  1. sqlite3.connect("score_db.db"):创建本地数据库文件,所有数据持久化存储
  2. CREATE TABLE IF NOT EXISTS:安全创建表,避免重复报错
  3. 主键AUTOINCREMENT:自动生成ID,无需手动维护
  4. 唯一约束UNIQUE:学号、用户名、班级名不重复,保证数据规范
  5. 初始化管理员:程序首次运行自动创建admin账号,开箱即用

✨二、核心模块二:GUI界面与登录权限系统

界面是系统的"门面",我们用PyQt5实现高颜值图形化界面,采用标签页布局、分组排版、自适应表格,整体不透明、精致高级;同时开发登录验证模块,实现管理员/教师双权限控制:管理员可操作全部功能,教师仅能查看学生管理、班级管理、成绩统计,无法访问教师管理模块,权限分明更安全。

这个模块包含登录窗口主界面窗口两大核心:登录窗口验证账号密码,主界面根据角色动态隐藏功能模块,界面自适应拉伸,表格自动适配宽度,操作逻辑极简。

完整代码

# ===================== 3. 登录窗口 =====================classLoginDialog(QDialog):def__init__(self):        super().__init__()        self.setWindowTitle("系统登录")        self.resize(300200)        self.username = ""        self.password = ""        self.role = ""# 表单布局:账号+密码输入框        layout = QFormLayout()        self.edit_user = QLineEdit()        self.edit_pwd = QLineEdit()        self.edit_pwd.setEchoMode(QLineEdit.Password)  # 密码隐藏        layout.addRow("账号:", self.edit_user)        layout.addRow("密码:", self.edit_pwd)        btn_login = QPushButton("登录")        btn_login.clicked.connect(self.check_login)        main_layout = QVBoxLayout()        main_layout.addLayout(layout)        main_layout.addWidget(btn_login)        self.setLayout(main_layout)# 登录验证:查询数据库匹配账号密码defcheck_login(self):        u = self.edit_user.text().strip()        p = self.edit_pwd.text().strip()        conn = sqlite3.connect("score_db.db")        c = conn.cursor()        c.execute("SELECT role FROM user WHERE username=? AND password=?", (u, p))        res = c.fetchone()        conn.close()if res:            self.username = u            self.role = res[0]            self.accept()  # 验证通过,打开主界面else:            QMessageBox.warning(self, "提示""账号或密码错误!")# ===================== 4. 主界面窗口 =====================classMainWin(QMainWindow):def__init__(self, user_role):        super().__init__()        self.role = user_role        self.db_path = "score_db.db"        self.initUI()definitUI(self):        self.setWindowTitle("PyQt5学生成绩管理系统")        self.resize(1200800)  # 初始窗口大小# 标签页布局:四大功能模块        self.tabs = QTabWidget()        self.tab_student = QWidget()        self.tab_class = QWidget()        self.tab_teacher = QWidget()        self.tab_stat = QWidget()        self.tabs.addTab(self.tab_student, "学生管理")        self.tabs.addTab(self.tab_class, "班级管理")        self.tabs.addTab(self.tab_teacher, "教师管理")        self.tabs.addTab(self.tab_stat, "成绩统计")# 权限控制:教师隐藏教师管理标签页if self.role != "admin":            self.tabs.removeTab(2)# 初始化各标签页功能        self.init_student_tab()        self.init_class_tab()        self.init_teacher_tab()        self.init_stat_tab()        self.setCentralWidget(self.tabs)

代码详解

  1. 登录窗口QDialog弹窗实现,密码框隐藏输入,数据库校验账号密码
  2. 权限控制:主界面接收登录角色,教师自动隐藏「教师管理」标签页
  3. 界面布局QTabWidget标签页+QVBoxLayout垂直布局,整洁美观
  4. 交互提示QMessageBox弹窗提示登录结果,用户体验更友好
  5. 窗口自适应:设置固定初始大小,界面元素自动适配

✨三、核心模块三:学生管理+数据可视化核心功能

这是系统的核心业务模块,包含学生信息的增删查改、Excel批量导入导出、成绩可视化统计,也是最实用的功能集合。我们实现了:

  1. 学生信息搜索、新增、表格展示
  2. Excel批量导入/导出,告别手动录入数据
  3. Matplotlib嵌入GUI,生成各科平均分柱状图
  4. 班级联动选择、成绩范围限制(0-100分),数据更规范

这个模块将PyQt5界面、Pandas数据处理、Matplotlib可视化完美结合,代码复用性强,功能全覆盖,满足日常教学管理所有需求。

完整代码

# ===================== 2. Matplotlib 图表画布 =====================classMplCanvas(FigureCanvasQTAgg):def__init__(self, parent=None, width=5, height=4, dpi=100):        fig = Figure(figsize=(width, height), dpi=dpi)        self.axes = fig.add_subplot(111)        super(MplCanvas, self).__init__(fig)# -------- 学生管理:搜索、新增、导入、导出 --------definit_student_tab(self):        layout = QVBoxLayout()# 搜索栏        h_search = QHBoxLayout()        self.edit_search = QLineEdit()        self.edit_search.setPlaceholderText("输入姓名/学号搜索")        btn_search = QPushButton("搜索")        btn_search.clicked.connect(self.load_student_data)        h_search.addWidget(self.edit_search)        h_search.addWidget(btn_search)# 操作按钮        h_btn = QHBoxLayout()        btn_add = QPushButton("新增学生")        btn_add.clicked.connect(self.add_student)        btn_export = QPushButton("导出Excel")        btn_export.clicked.connect(self.export_student)        btn_import = QPushButton("导入Excel")        btn_import.clicked.connect(self.import_student)        h_btn.addWidget(btn_add)        h_btn.addWidget(btn_export)        h_btn.addWidget(btn_import)# 学生表格:自适应宽度        self.table_stu = QTableWidget()        self.table_stu.setColumnCount(8)        self.table_stu.setHorizontalHeaderLabels(["ID""学号""姓名""性别""班级""语文""数学""英语"])        self.table_stu.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)        layout.addLayout(h_search)        layout.addLayout(h_btn)        layout.addWidget(self.table_stu)        self.tab_student.setLayout(layout)        self.load_student_data()# -------- 成绩统计可视化 --------definit_stat_tab(self):        layout = QVBoxLayout()        self.canvas = MplCanvas(self)        btn_refresh = QPushButton("刷新统计(平均分)")        btn_refresh.clicked.connect(self.draw_stat)        layout.addWidget(btn_refresh)        layout.addWidget(self.canvas)        self.tab_stat.setLayout(layout)# 绘制各科平均分柱状图defdraw_stat(self):        conn = sqlite3.connect(self.db_path)        df = pd.read_sql("SELECT chinese,math,english FROM student", conn)        conn.close()if df.empty:            QMessageBox.warning(self, "提示""暂无学生数据")return# 计算平均分        avg = [df["chinese"].mean(), df["math"].mean(), df["english"].mean()]        sub = ["语文""数学""英语"]# 绘图并渲染到GUI        self.canvas.axes.clear()        self.canvas.axes.bar(sub, avg, color=["#ff9999""#66b3ff""#99ff99"])        self.canvas.axes.set_title("各科平均分统计")        self.canvas.draw()

代码详解

  1. 图表画布MplCanvas类将Matplotlib图表嵌入PyQt5界面,实现GUI内可视化
  2. 学生搜索:支持姓名/学号模糊搜索,实时刷新表格
  3. Excel操作pandas实现一键导入导出,批量处理数据效率拉满
  4. 成绩统计:自动计算三科平均分,生成彩色柱状图,直观展示数据
  5. 数据校验:新增学生时限制成绩0-100分,学号非空且唯一,保证数据质量

📚 系统完整可运行代码

将以上所有模块整合,就是完整的学生成绩管理系统,直接复制运行即可使用

import sysimport osimport sqlite3import pandas as pdfrom PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,                             QPushButton, QLineEdit, QLabel, QTableWidget, QTableWidgetItem,                             QDialog, QFormLayout, QComboBox, QMessageBox, QFileDialog,                             QTabWidget, QGroupBox, QHeaderView, QSpinBox)from PyQt5.QtCore import Qtfrom matplotlib.backends.backend_qt5agg import FigureCanvasQTAggfrom matplotlib.figure import Figure# ===================== 1. 数据库初始化 =====================definit_db():    conn = sqlite3.connect("score_db.db")    c = conn.cursor()# 用户表(管理员/教师)    c.execute('''CREATE TABLE IF NOT EXISTS user                 (id INTEGER PRIMARY KEY AUTOINCREMENT,                  username TEXT UNIQUE,                  password TEXT,                  role TEXT,  -- admin/teacher                  class_id INTEGER)''')# 班级表    c.execute('''CREATE TABLE IF NOT EXISTS class                 (id INTEGER PRIMARY KEY AUTOINCREMENT,                  class_name TEXT UNIQUE)''')# 学生表    c.execute('''CREATE TABLE IF NOT EXISTS student                 (id INTEGER PRIMARY KEY AUTOINCREMENT,                  stu_id TEXT UNIQUE,                  name TEXT,                  gender TEXT,                  class_id INTEGER,                  chinese INTEGER,                  math INTEGER,                  english INTEGER)''')# 初始化超级管理员    c.execute("SELECT * FROM user WHERE username='admin'")ifnot c.fetchone():        c.execute("INSERT INTO user(username,password,role) VALUES ('admin','123456','admin')")    conn.commit()    conn.close()# ===================== 2. Matplotlib 图表画布 =====================classMplCanvas(FigureCanvasQTAgg):def__init__(self, parent=None, width=5, height=4, dpi=100):        fig = Figure(figsize=(width, height), dpi=dpi)        self.axes = fig.add_subplot(111)        super(MplCanvas, self).__init__(fig)# ===================== 3. 登录窗口 =====================classLoginDialog(QDialog):def__init__(self):        super().__init__()        self.setWindowTitle("系统登录")        self.resize(300200)        self.username = ""        self.password = ""        self.role = ""        layout = QFormLayout()        self.edit_user = QLineEdit()        self.edit_pwd = QLineEdit()        self.edit_pwd.setEchoMode(QLineEdit.Password)        layout.addRow("账号:", self.edit_user)        layout.addRow("密码:", self.edit_pwd)        btn_login = QPushButton("登录")        btn_login.clicked.connect(self.check_login)        main_layout = QVBoxLayout()        main_layout.addLayout(layout)        main_layout.addWidget(btn_login)        self.setLayout(main_layout)defcheck_login(self):        u = self.edit_user.text().strip()        p = self.edit_pwd.text().strip()        conn = sqlite3.connect("score_db.db")        c = conn.cursor()        c.execute("SELECT role FROM user WHERE username=? AND password=?", (u, p))        res = c.fetchone()        conn.close()if res:            self.username = u            self.role = res[0]            self.accept()else:            QMessageBox.warning(self, "提示""账号或密码错误!")# ===================== 4. 主界面窗口 =====================classMainWin(QMainWindow):def__init__(self, user_role):        super().__init__()        self.role = user_role        self.db_path = "score_db.db"        self.initUI()definitUI(self):        self.setWindowTitle("PyQt5学生成绩管理系统")        self.resize(1200800)# 标签页        self.tabs = QTabWidget()        self.tab_student = QWidget()        self.tab_class = QWidget()        self.tab_teacher = QWidget()        self.tab_stat = QWidget()        self.tabs.addTab(self.tab_student, "学生管理")        self.tabs.addTab(self.tab_class, "班级管理")        self.tabs.addTab(self.tab_teacher, "教师管理")        self.tabs.addTab(self.tab_stat, "成绩统计")# 权限隐藏:教师看不到教师管理if self.role != "admin":            self.tabs.removeTab(2)        self.init_student_tab()        self.init_class_tab()        self.init_teacher_tab()        self.init_stat_tab()        self.setCentralWidget(self.tabs)# -------- 学生管理 --------definit_student_tab(self):        layout = QVBoxLayout()# 搜索栏        h_search = QHBoxLayout()        self.edit_search = QLineEdit()        self.edit_search.setPlaceholderText("输入姓名/学号搜索")        btn_search = QPushButton("搜索")        btn_search.clicked.connect(self.load_student_data)        h_search.addWidget(self.edit_search)        h_search.addWidget(btn_search)# 操作按钮        h_btn = QHBoxLayout()        btn_add = QPushButton("新增学生")        btn_add.clicked.connect(self.add_student)        btn_export = QPushButton("导出Excel")        btn_export.clicked.connect(self.export_student)        btn_import = QPushButton("导入Excel")        btn_import.clicked.connect(self.import_student)        h_btn.addWidget(btn_add)        h_btn.addWidget(btn_export)        h_btn.addWidget(btn_import)# 表格        self.table_stu = QTableWidget()        self.table_stu.setColumnCount(8)        self.table_stu.setHorizontalHeaderLabels(["ID""学号""姓名""性别""班级""语文""数学""英语"])        self.table_stu.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)        layout.addLayout(h_search)        layout.addLayout(h_btn)        layout.addWidget(self.table_stu)        self.tab_student.setLayout(layout)        self.load_student_data()defload_student_data(self):        key = self.edit_search.text().strip()        conn = sqlite3.connect(self.db_path)if key:            sql = '''SELECT s.id,s.stu_id,s.name,s.gender,c.class_name,s.chinese,s.math,s.english                     FROM student s LEFT JOIN class c ON s.class_id=c.id                     WHERE s.name LIKE ? OR s.stu_id LIKE ?'''            res = pd.read_sql(sql, conn, params=(f"%{key}%"f"%{key}%"))else:            sql = '''SELECT s.id,s.stu_id,s.name,s.gender,c.class_name,s.chinese,s.math,s.english                     FROM student s LEFT JOIN class c ON s.class_id=c.id'''            res = pd.read_sql(sql, conn)        conn.close()        self.table_stu.setRowCount(len(res))for i, row in res.iterrows():for j, val in enumerate(row):                self.table_stu.setItem(i, j, QTableWidgetItem(str(val)))defadd_student(self):        dlg = QDialog()        dlg.setWindowTitle("新增学生")        form = QFormLayout()        e_stuid = QLineEdit()        e_name = QLineEdit()        c_gender = QComboBox()        c_gender.addItems(["男""女"])        c_class = QComboBox()# 加载班级        conn = sqlite3.connect(self.db_path)        cls = pd.read_sql("SELECT id,class_name FROM class", conn)        conn.close()for _, r in cls.iterrows():            c_class.addItem(r["class_name"], r["id"])        e_chs = QSpinBox()        e_math = QSpinBox()        e_eng = QSpinBox()for w in [e_chs, e_math, e_eng]:            w.setRange(0100)        form.addRow("学号:", e_stuid)        form.addRow("姓名:", e_name)        form.addRow("性别:", c_gender)        form.addRow("班级:", c_class)        form.addRow("语文:", e_chs)        form.addRow("数学:", e_math)        form.addRow("英语:", e_eng)defsave():            stuid = e_stuid.text().strip()            name = e_name.text().strip()            cid = c_class.currentData()ifnot stuid ornot name:                QMessageBox.warning(dlg, "提示""学号姓名不能为空")return            conn = sqlite3.connect(self.db_path)try:                conn.execute('''INSERT INTO student(stu_id,name,gender,class_id,chinese,math,english)                                VALUES (?,?,?,?,?,?,?)''',                             (stuid, name, c_gender.currentText(), cid, e_chs.value(), e_math.value(), e_eng.value()))                conn.commit()                QMessageBox.information(dlg, "成功""添加完成")                dlg.accept()                self.load_student_data()except:                QMessageBox.warning(dlg, "错误""学号重复!")            conn.close()        btn_ok = QPushButton("保存")        btn_ok.clicked.connect(save)        vbox = QVBoxLayout()        vbox.addLayout(form)        vbox.addWidget(btn_ok)        dlg.setLayout(vbox)        dlg.exec_()defexport_student(self):        path, _ = QFileDialog.getSaveFileName(self, "导出Excel""学生成绩.xlsx""Excel(*.xlsx)")ifnot path: return        conn = sqlite3.connect(self.db_path)        df = pd.read_sql('''SELECT * FROM student''', conn)        conn.close()        df.to_excel(path, index=False)        QMessageBox.information(self, "提示""导出成功")defimport_student(self):        file, _ = QFileDialog.getOpenFileName(self, "选择Excel""""Excel(*.xlsx)")ifnot file: returntry:            df = pd.read_excel(file)            conn = sqlite3.connect(self.db_path)            df.to_sql("student", conn, if_exists="append", index=False)            conn.commit()            conn.close()            self.load_student_data()            QMessageBox.information(self, "提示""导入成功")except Exception as e:            QMessageBox.warning(self, "错误"f"导入失败:{str(e)}")# -------- 班级管理 --------definit_class_tab(self):        layout = QVBoxLayout()        h_btn = QHBoxLayout()        self.table_cls = QTableWidget()        self.table_cls.setColumnCount(2)        self.table_cls.setHorizontalHeaderLabels(["ID""班级名称"])        self.table_cls.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)defadd_cls():            name, ok = QInputDialog.getText(self, "新增班级""请输入班级名称:")ifnot ok ornot name: return            conn = sqlite3.connect(self.db_path)try:                conn.execute("INSERT INTO class(class_name) VALUES (?)", (name,))                conn.commit()                self.load_class_data()                QMessageBox.information(self, "成功""班级添加成功!")except:                QMessageBox.warning(self, "错误""班级已存在")            conn.close()        btn_add = QPushButton("新增班级")        btn_add.clicked.connect(add_cls)        h_btn.addWidget(btn_add)        layout.addLayout(h_btn)        layout.addWidget(self.table_cls)        self.tab_class.setLayout(layout)        self.load_class_data()defload_class_data(self):        conn = sqlite3.connect(self.db_path)        res = pd.read_sql("SELECT * FROM class", conn)        conn.close()        self.table_cls.setRowCount(len(res))for i, row in res.iterrows():            self.table_cls.setItem(i, 0, QTableWidgetItem(str(row["id"])))            self.table_cls.setItem(i, 1, QTableWidgetItem(row["class_name"]))# -------- 教师管理 --------definit_teacher_tab(self):        layout = QVBoxLayout()        self.table_tea = QTableWidget()        self.table_tea.setColumnCount(4)        self.table_tea.setHorizontalHeaderLabels(["账号""密码""角色""绑定班级"])        self.table_tea.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)        layout.addWidget(self.table_tea)        self.tab_teacher.setLayout(layout)        self.load_teacher_data()defload_teacher_data(self):        conn = sqlite3.connect(self.db_path)        res = pd.read_sql("SELECT username,password,role,class_id FROM user", conn)        conn.close()        self.table_tea.setRowCount(len(res))for i, row in res.iterrows():            self.table_tea.setItem(i, 0, QTableWidgetItem(row["username"]))            self.table_tea.setItem(i, 1, QTableWidgetItem(row["password"]))            self.table_tea.setItem(i, 2, QTableWidgetItem(row["role"]))            self.table_tea.setItem(i, 3, QTableWidgetItem(str(row["class_id"])))# -------- 成绩统计图表 --------definit_stat_tab(self):        layout = QVBoxLayout()        self.canvas = MplCanvas(self)        btn_refresh = QPushButton("刷新统计(平均分)")        btn_refresh.clicked.connect(self.draw_stat)        layout.addWidget(btn_refresh)        layout.addWidget(self.canvas)        self.tab_stat.setLayout(layout)defdraw_stat(self):        conn = sqlite3.connect(self.db_path)        df = pd.read_sql("SELECT chinese,math,english FROM student", conn)        conn.close()if df.empty:            QMessageBox.warning(self, "提示""暂无学生数据")return        avg = [df["chinese"].mean(), df["math"].mean(), df["english"].mean()]        sub = ["语文""数学""英语"]        self.canvas.axes.clear()        self.canvas.axes.bar(sub, avg, color=["#ff9999""#66b3ff""#99ff99"])        self.canvas.axes.set_title("各科平均分统计")        self.canvas.draw()# ===================== 程序入口 =====================if __name__ == "__main__":    init_db()    app = QApplication(sys.argv)    login = LoginDialog()if login.exec_():        win = MainWin(login.role)        win.show()        sys.exit(app.exec_())

📝 知识点总结

  1. GUI开发:PyQt5常用组件(窗口、标签页、表格、按钮、输入框)、布局管理、信号槽机制
  2. 数据库操作:SQLite轻量数据库使用、建表语句、增删查改、数据约束
  3. 数据处理:Pandas读取数据库、Excel导入导出、数据计算
  4. 数据可视化:Matplotlib嵌入PyQt5、柱状图绘制、图表刷新
  5. 权限系统:角色判断、功能动态隐藏、登录验证逻辑
  6. 工程化:模块化代码设计、函数封装、异常处理

🚀 拓展场景与测试步骤

一、测试步骤(快速上手)

  1. 安装依赖:pip install pyqt5 pandas matplotlib openpyxl
  2. 运行代码,自动生成score_db.db数据库文件
  3. 登录账号:admin,密码:123456
  4. 先在「班级管理」添加班级,再在「学生管理」新增学生
  5. 测试搜索、导入导出、成绩统计功能,验证权限区分

二、拓展场景

  1. 功能拓展:添加学生信息修改/删除、成绩排名、单科成绩筛选
  2. 界面美化:更换主题、添加图标、调整配色,提升高级感
  3. 数据拓展:增加更多科目、学生详情信息、成绩导出为PDF
  4. 权限拓展:添加学生端登录,仅查看个人成绩
  5. 部署拓展:打包为exe可执行文件,无Python环境也能运行

这款系统完美融合了Python三大核心技能,是GUI开发、数据库、数据可视化的绝佳实战项目,无论是学习练手还是实际使用,都能轻松满足需求!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-15 18:08:36 HTTP/2.0 GET : https://f.mffb.com.cn/a/486094.html
  2. 运行时间 : 0.079250s [ 吞吐率:12.62req/s ] 内存消耗:4,646.01kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=1c4ba634f2145ee0af09364a4639e32c
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000705s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000770s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000308s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000263s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000526s ]
  6. SELECT * FROM `set` [ RunTime:0.000208s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000565s ]
  8. SELECT * FROM `article` WHERE `id` = 486094 LIMIT 1 [ RunTime:0.001664s ]
  9. UPDATE `article` SET `lasttime` = 1776247716 WHERE `id` = 486094 [ RunTime:0.001825s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000271s ]
  11. SELECT * FROM `article` WHERE `id` < 486094 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000427s ]
  12. SELECT * FROM `article` WHERE `id` > 486094 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000614s ]
  13. SELECT * FROM `article` WHERE `id` < 486094 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001311s ]
  14. SELECT * FROM `article` WHERE `id` < 486094 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000654s ]
  15. SELECT * FROM `article` WHERE `id` < 486094 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001303s ]
0.080977s