新闻详情

新闻详情

首页 / 资讯中心 / 详情

Python+Qt+MySQL学生管理系统源码实战:从环境搭建到打包发布

发布时间:2026/9/16 20:32:18来源:尧图网络
Python+Qt+MySQL学生管理系统源码实战:从环境搭建到打包发布
简介这是一套基于Python、Qt界面库与MySQL数据库实现的学生管理系统完整源码面向希望提升桌面应用开发、数据库设计及GUI编程能力的初学者与开发者也适合作为高校课程设计或毕业设计的参考项目。项目覆盖登录认证、学生信息维护、成绩查询等典型模块代码中体现MVC分层、PyQt控件使用、SQL语句编写、异常处理与日志记录等实战要点可帮助读者将零散知识点串联成完整开发链路。压缩包共30个文件以13个py源码文件与11个ui界面设计文件为主另含SQL建表脚本、图标样式资源及说明文档包体仅276KB结构清晰便于按模块研读。从数据库表结构设计、界面布局到业务逻辑实现均有完整呈现源码注释与模块划分便于二次开发配套SQL脚本可快速导入数据表并复现运行环境。目前已有1218人学习下载适合作为课程设计参考或入门级管理系统的完整范例。1. 学生管理系统源码Python Qt MySQL解决什么问题从网盘或课程附件里下载的“学生管理系统源码Python Qt MySQL.zip”解压后通常是一堆 .py、一个 .ui、一个 .sqlREADME 写着“运行 main.py”。真正运行时却会接连踩坑有的报 qt.qpa.platform 找不到平台插件有的是 MySQL 1045 密码错误还有的是装完 PyQt5 后 import 直接失败。这个标题组合本质上是桌面端最经典的三层结构Qt 负责窗口与交互Python 负责业务逻辑MySQL 负责持久化。对刚入门的人来说它是一份能看懂的增删改查范本对需要给实验室、教务组做内部工具的人来说它是一个比 Web 端更轻量的落地路径。这篇文章从环境、界面、数据层、打包发布四个环节拆开讲重点说源码包里 README 不会写清楚的边界条件。2. 环境搭建与三层架构先让 Python、Qt、MySQL 连成一个整体在打开源码之前先确认三件事Python 解释器、Qt 绑定库、MySQL 服务是否就绪。这个顺序不要反过来否则报错了很难分清是环境问题还是代码问题。先装 Python 3.10 或 3.11安装时勾选 Add Python to PATH这步漏了后面在命令行执行 python 就会报“不是内部或外部命令”。2.1 选型PySide6、PyQt5 与 PyMySQL 怎么搭配现在能用的 Qt 绑定有两套PyQt5 和 PySide6。老源码里最常见的是 PyQt5教程和现成代码也最多PySide6 是 Qt 官方绑定API 与 PyQt5 几乎一致区别在许可证——PySide6 是 LGPL做内部工具更保险。判断源码头文件用的是哪一个看 main.py 顶部from PyQt5.QtWidgets import QApplication, QWidget # 情况一 from PySide6.QtWidgets import QApplication, QWidget # 情况二这两套库不能同时装安装时二选一。如果你要运行的是旧项目建议保留 PyQt5如果是新写直接上 PySide6。数据库驱动方面PyMySQL 是纯 Python 实现能兼容 MySQL 8.0 的 caching_sha2_password 认证这也是大多数学生管理源码选择它的原因。2.2 从 Python 安装到 MySQL 启动的实操顺序先在命令行验证基础环境python --version mysql --version pip --version如果 python 有版本号而 mysql 没有先安装 MySQL 8.0。Windows 下用 MySQL Installer 选 Server Only配置端口保持 3306编码选 utf8mb4Linux 下用 apt 安装后需要手动启动sudo systemctl start mysql sudo systemctl enable mysql sudo mysql_secure_installation再安装 Python 依赖pip install PyQt5 PyMySQL在使用 VSCode 做 Python 环境配置时先按 CtrlShiftP 选择解释器再在终端里执行 pip install否则容易装到另一个 Python 版本里。检查是否装对pip show pyqt5 pymysql注意这一步最常见的错误原因有两个pip 装到了用户目录而解释器指向虚拟环境或者命令行 python 是 3.8VSCode 里用的是 3.11import 时找不到 Qt。2.3 源码目录划分与最小数据库连接代码一个能长期维护的学生管理源码文件不会全堆在一个 .py 里。常见做法是拆成这样student_manager/ main.py # 程序入口先启动登录窗口 db.py # 数据库连接与公共查询封装 ui/ login_window.py # 登录界面 main_window.py # 学生管理主界面 models/ student.py # 学生实体我一般会在 db.py 里放一个 get_conn()所有窗口都从它拿连接import pymysql def get_conn(): return pymysql.connect( host127.0.0.1, port3306, userroot, passwordyour_password, databasestudent_db, charsetutf8mb4, cursorclasspymysql.cursors.DictCursor, autocommitTrue, )这段代码里有几个参数值得说明host 写 127.0.0.1 而不是 localhost避免 Linux 上 PyMySQL 走 socket 造成连接失败charset 用 utf8mb4才能存生僻字和 emojiautocommitTrue 让增删改不需要手动 commitDictCursor 把查询结果映射成字典读取时 row[name] 比 row[0] 可读性高。然后写一个最小启动验证try: conn get_conn() print(MySQL 连接成功, conn) conn.close() except Exception as e: print(连接失败请确认 MySQL 服务已启动, e)如果报 1045 Access denied检查用户名密码报 2003 Cant connect说明 MySQL 服务没启动或端口被改报 1049 Unknown database先建库。这一步跑通了Qt 界面才拿得到数据。3. Qt 界面层登录窗口到学生列表信号槽与表格控件的常见坑Qt 界面层是学生管理系统里代码量最大的一层也是初学者最容易写出“能跑但没法维护”代码的地方。核心问题是两件界面用工具生成还是手写以及数据怎么从输入框到 SQL 再回到表格。3.1 Qt Designer 还是纯代码生成界面改源码的切入点很多源码包里会带 .ui 文件这是 Qt Designer 的可视化布局文件。用 .ui 的好处是拖拽就能完成窗口布局坏处是运行时需要加载动态界面。常见的转换方式是pyuic5 -o ui_login.py login.ui如果源码里只有 login.ui 而没有生成的 ui_login.py需要自己执行这行命令。反过来有的源码直接用 Python 代码写布局例如self.name_edit QLineEdit(self) self.name_edit.setPlaceholderText(请输入学号或姓名) self.query_btn QPushButton(查 询, self) self.query_btn.clicked.connect(self.on_query)两套方案维护成本不同QSS 样式、控件属性大多可以在 Designer 里直接设置而动态生成或者纯代码布局在版本升级时更容易冲突。我一般建议界面结构用 Designer业务逻辑在生成的 .py 里不要做任何修改而是另外写一个控制器类去继承它这样源码升级时重新生成 .ui 不会覆盖你的业务代码。3.2 登录窗口的信号槽、输入校验与 qt 国际化处理学生管理系统的登录窗口一般包含账号输入框、密码输入框和登录按钮核心逻辑是校验输入非空再去数据库比对。完整示例from PyQt5.QtWidgets import QMessageBox from PyQt5.QtCore import QTranslator, QLocale import db class LoginWindow(QWidget): def __init__(self): super().__init__() self.user_edit QLineEdit(self) self.pwd_edit QLineEdit(self) self.pwd_edit.setEchoMode(QLineEdit.Password) self.login_btn QPushButton(登 录, self) self.login_btn.clicked.connect(self.handle_login) def handle_login(self): username self.user_edit.text().strip() password self.pwd_edit.text().strip() if not username or not password: QMessageBox.warning(self, 提示, 账号和密码不能为空) return conn db.get_conn() cursor conn.cursor() cursor.execute( SELECT * FROM admin WHERE username%s AND password%s, (username, password) ) if cursor.fetchone(): self.accept() else: QMessageBox.critical(self, 错误, 用户名或密码错误)setEchoMode(QLineEdit.Password) 可以把输入显示为圆点strip() 去掉用户误输的空格避免把“admin ”当成合法账号。SQL 里用好占位符 %s而不是拼字符串这一步是防注入的第一道防线。如果源码用到 qt 国际化也就是语言切换需要在 main.py 里提前加载翻译文件translator QTranslator() translator.load(QLocale.system(), base_) app.installTranslator(translator)常见做法是加载 Qt 自带的 qt_zh_CN.qm到 Qt 安装目录的 translations 路径下找自己业务上的中文提示一般不需要走翻译流程直接写中文即可。3.3 学生列表QTableWidget 绑定 MySQL 查询结果列表展示通常用 QTableWidget数据量几百条以内完全没有压力。核心代码如下from PyQt5.QtWidgets import (QTableWidget, QTableWidgetItem, QHeaderView) def load_students(self, keyword): conn db.get_conn() cursor conn.cursor() if keyword: cursor.execute( SELECT id, student_no, name, gender, age, class_name FROM student WHERE name LIKE %s ORDER BY id DESC, (% keyword %,) ) else: cursor.execute( SELECT id, student_no, name, gender, age, class_name FROM student ORDER BY id DESC ) rows cursor.fetchall() self.table.setRowCount(len(rows)) for i, row in enumerate(rows): self.table.setItem(i, 0, QTableWidgetItem(str(row[student_no]))) self.table.setItem(i, 1, QTableWidgetItem(row[name])) self.table.setItem(i, 2, QTableWidgetItem(row[gender])) self.table.setItem(i, 3, QTableWidgetItem(str(row[age]))) self.table.setItem(i, 4, QTableWidgetItem(row[class_name])) self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)参数说明QTableWidget.setItem 的列索引要和查询结果的字段顺序对应setSectionResizeMode(QHeaderView.Stretch) 让列宽均分避免窗口拉伸后留白。这里有一个性能边界setItem 逐行插入在 500 行内没明显延迟超过 1000 行建议改用 QTableView QStandardItemModel因为 QTableWidget 的每条 Item 都是独立对象内存占用高。如果列表里要显示“操作”按钮比如每行的“编辑”“删除”不要用 QPushButton 直接放表格最好在按钮点击信号里通过 sender() 拿到当前行再取该行的 id 字段具体做法在增删改查章节展开。4. MySQL 数据层表设计、索引、存储过程与参数化查询学生管理系统的业务不复杂但数据层的质量决定了系统能跑多久。很多源码包里的 .sql 只建了三张表没有外键也没有索引把系统用在真实环境后数据一多查询就慢这时候回头补索引的成本比一开始设计高得多。4.1 学生库表设计与字段选择索引建在哪里一个标准的学生管理数据库至少包含这三张表CREATE DATABASE IF NOT EXISTS student_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci; USE student_db; CREATE TABLE admin ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE, name VARCHAR(50) NOT NULL, gender ENUM(男, 女) DEFAULT 男, age TINYINT UNSIGNED, class_name VARCHAR(100), addr VARCHAR(255), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_name (name), INDEX idx_class (class_name) ); CREATE TABLE score ( id INT PRIMARY KEY AUTO_INCREMENT, student_id INT NOT NULL, course_name VARCHAR(100), score DECIMAL(5,2), exam_date DATE, FOREIGN KEY (student_id) REFERENCES student(id) ON DELETE CASCADE, INDEX idx_student_course (student_id, course_name) );几个设计点值得注意student_no 加 UNIQUE确保同一个学号不会重复录入age 用 TINYINT UNSIGNED取值范围 0 到 255比 INT 省存储字符串字段按需设定长度不要一上来就 VARCHAR(255)。外键在源码包里很少见但如果涉及成绩表用 FOREIGN KEY ON DELETE CASCADE 可以避免产生孤立的成绩记录。用 MySQL Workbench 打开这个 .sql 执行可以直接看到表关系的实体图方便初学者理解三张表如何关联。建立索引的经验是WHERE 里常用的字段建 INDEX组合查询场景建联合索引。把 idx_student_course 放在 score 表上是因为成绩查询总是先按 student_id 筛选再按 course_name 排序单独在 course_name 上建索引意义不大。4.2 用 MySQL 存储过程简化统计代码学生管理系统里常见的统计需求是“每个班的平均分、最高分、最低分”这类聚合查询放到存储过程里可以避免在 Python 层写冗长的 GROUP BY 拼接。基本写法DELIMITER // CREATE PROCEDURE sp_class_avg(IN class_name_param VARCHAR(100)) BEGIN SELECT s.class_name, COUNT(DISTINCT s.id) AS student_count, ROUND(AVG(sc.score), 2) AS avg_score, MAX(sc.score) AS max_score, MIN(sc.score) AS min_score FROM student s JOIN score sc ON s.id sc.student_id WHERE s.class_name class_name_param GROUP BY s.class_name; END // DELIMITER ;调用方式CALL sp_class_avg(计算机2302班);再用 Python 调用cursor.callproc(sp_class_avg, (计算机2302班,)) for result in cursor.stored_results(): rows result.fetchall()参数说明第一个参数是存储过程名第二个参数是列表形式传给 IN 参数stored_results() 取回游标结果。使用存储过程的收益在数据量小的时候看不出区别数据量大了以后SQL 编译和网络往返都集中在数据库端应用层代码会清爽很多。需要注意 DELIMITER 只在命令行和 Workbench 中生效Python 里写存储过程定义时不要带这一行。4.3 PyMySQL 参数化查询防止 SQL 注入学生管理系统是教学项目但也不能忽略注入风险。下面两种写法效果完全不同# 错误写法源码包里偶尔见到 cursor.execute( SELECT * FROM student WHERE name %s % keyword ) # 正确写法 cursor.execute( SELECT * FROM student WHERE name %s, (keyword,) )第一种写法在 Python 层把 user 输入直接拼进 SQL如果用户在输入框里填了 OR 11拼接后是恒真条件整个表都会查出来。第二种写法把 SQL 模板和参数分两个参数传给 PyMySQL驱动层会做转义处理。需要记住的原则只有一条永远不要用格式化字符串拼 SQL。查询学生信息接口建议统一封装成函数方便复用def query_students(keyword, class_name): conn db.get_conn() cursor conn.cursor() sql SELECT id, student_no, name, gender, age, class_name FROM student WHERE 11 params [] if keyword: sql AND (student_no LIKE %s OR name LIKE %s) params.extend([% keyword %] * 2) if class_name: sql AND class_name %s params.append(class_name) sql ORDER BY id DESC cursor.execute(sql, tuple(params)) return cursor.fetchall()这样组织的查询列表功能不需要为精确查询和模糊查询各写一套方法调用方只需控制传入参数。Python 的类型转换在这里也要留意传进来的 keyword 如果是数字先 str() 再拼进 LIKE否则 MySQL 比较时可能出现隐式转换警告。5. 业务功能落全增删改查的完整实现与自动备份脚本数据层通了界面层有了剩下的就是四个基本操作。学生管理源码的实用价值全在这里录入、查找、修改、删除再加一个数据库备份。我按一个窗口内完成全部操作的思路来写不做多级菜单跳转降低初学者的理解成本。5.1 添加学生input 输入框取值与 insert 的字段对应添加学生的界面一般包含学号、姓名、性别、年龄、班级等输入框。提交按钮的槽函数def on_add_student(self): student_no self.edit_no.text().strip() name self.edit_name.text().strip() gender self.combo_gender.currentText() age_text self.edit_age.text().strip() class_name self.edit_class.text().strip() if not student_no or not name: QMessageBox.warning(self, 提示, 学号和姓名不能为空) return try: age int(age_text) if age_text else 0 except ValueError: QMessageBox.warning(self, 提示, 年龄必须为数字) return conn db.get_conn() cursor conn.cursor() try: cursor.execute( INSERT INTO student (student_no, name, gender, age, class_name) VALUES (%s, %s, %s, %s, %s), (student_no, name, gender, age, class_name) ) QMessageBox.information(self, 成功, 学生信息已添加) self.load_students() except pymysql.err.IntegrityError: QMessageBox.critical(self, 错误, 该学号已存在)这段代码有三个关键点年龄先 int() 转换用户输入“abc”时 catch 住不至于让程序崩溃学号冲突会抛 IntegrityError单独处理给出友好提示添加成功后立刻调 load_students() 刷新表格不要等用户手动点刷新。Python 里变量定义要尽量靠近使用处age 这种中间变量临时定义即可不需要在函数顶部全部声明。5.2 查询学生学号精确查、姓名模糊查的 SQL 写法查询框做成一个关键字入口内部区分学号和姓名def on_search(self): keyword self.edit_search.text().strip() if not keyword: self.load_students() return conn db.get_conn() cursor conn.cursor() cursor.execute( SELECT id, student_no, name, gender, age, class_name FROM student WHERE student_no %s UNION SELECT id, student_no, name, gender, age, class_name FROM student WHERE name LIKE %s ORDER BY id DESC, (keyword, % keyword %) ) # 或者忽略性别只按 name LIKE这里演示精确与模糊并存 rows cursor.fetchall() self.table.setRowCount(len(rows)) for i, row in enumerate(rows): self.table.setItem(i, 0, QTableWidgetItem(str(row[student_no]))) self.table.setItem(i, 1, QTableWidgetItem(row[name])) self.table.setItem(i, 2, QTableWidgetItem(row[gender])) self.table.setItem(i, 3, QTableWidgetItem(str(row[age]))) self.table.setItem(i, 4, QTableWidgetItem(row[class_name])) if not rows: QMessageBox.information(self, 提示, 没有找到匹配的学生)学号一般要求精确姓名支持模糊所以两条 SELECT 用 UNION 合并。注意 UNION 会自动去重如果同一人学号和姓名都命中只显示一次如果你希望两条都显示改成 UNION ALL。第一种查询因此可能返回重复行所以实际更常见的是只按name LIKE %keyword%匹配在 SQL 里用 OR 连接两个条件WHERE student_no %s OR name LIKE %s两者性能差异很小用 OR 的可读性更好。模糊查询的 % 必须放在参数里不要放在 SQL 模板里原因和前面防注入一致。5.3 修改与删除以主键为条件的 update 和 delete表格里每一行存的是学生数据删除和编辑必须知道这一行对应的主键 id。常见做法是在 QTableWidget 的单元格上存 id或者用一个 Python dict 记录行的 idself.row_id_map {} def load_students(self, rows): self.table.setRowCount(len(rows)) self.row_id_map.clear() for i, row in enumerate(rows): self.row_id_map[i] row[id] # 填充单元格代码省略 def delete_selected(self): row self.table.currentRow() if row 0: QMessageBox.warning(self, 提示, 请先选择要删除的行) return student_id self.row_id_map.get(row) confirm QMessageBox.question( self, 确认, 确定删除该学生吗 ) if confirm ! QMessageBox.Yes: return conn db.get_conn() cursor conn.cursor() cursor.execute(DELETE FROM student WHERE id %s, (student_id,)) self.load_students()修改的逻辑类似但要注意更新语句必须带主键条件否则会出现把所有学生性别更新成同一个值的惨案。编辑时把当前行数据回填到输入框def edit_selected(self): row self.table.currentRow() item self.table.item(row, 1) # name 列 self.edit_name.setText(item.text()) self.current_edit_id self.row_id_map[row]接下来点击保存按钮时如果是编辑状态就走 UPDATE 而不是 INSERT。用一个标志位区分新增和编辑等提交完成后重置。更新语句cursor.execute( UPDATE student SET student_no%s, name%s, gender%s, age%s, class_name%s WHERE id%s, (student_no, name, gender, age, class_name, self.current_edit_id) )参数占位符数量和顺序一定要与 SQL 模板里的 %s 一一对应少一个或多一个都会在运行时抛 ProgrammingError和报错位置的堆栈往往不相关一眼看不出错在哪里。5.4 数据安全mysqldump 自动备份的 bat 脚本学生管理系统的数据量不大但数据丢不起。Windows 下写一个自动备份脚本加入计划任务每天定时跑echo off set BACKUP_DIRD:\student_backup set MYSQL_BIND:\mysql-8.0\bin set DATE_STR%date:~0,4%%date:~5,2%%date:~8,2% set FILE_NAMEstudent_%DATE_STR%.sql %MYSQL_BIN%\mysqldump.exe -u root -p123456 student_db %BACKUP_DIR%\%FILE_NAME% echo 备份完成: %BACKUP_DIR%\%FILE_NAME%参数说明date 命令的不同系统区域可能出现格式差异这里假设格式是 2025-01-15所以 %date:~0,4% 取年、%date:~5,2% 取月、%date:~8,2% 取日。mysqldump 路径必须全路径否则在计划任务里会提示找不到命令密码写在命令行里有泄露风险内网工具可用公网环境改用 my.cnf 的 [client] 节配置。恢复备份时把 SQL 文件直接导入mysql -u root -p student_db student_20250115.sql导入前先确认 student_db 库存在不存在则先 CREATE DATABASE。备份文件命名里带日期可以按天留存必要时再写一个只保留最近 30 天的 forfiles 清理命令。6. PyInstaller 打包发布隐藏源码、处理数据文件与常见报错开发环境下程序跑得通只是第一步交付给使用者时不能让对方也装一套 Python 和 MySQL。打包发布这一节讲的都是实际经常踩的坑尤其是 PyInstaller 打包 PyQt5 程序时经常遇到的平台插件错误。6.1 PyInstaller 打包命令与 .ui 文件处理安装打包工具pip install pyinstaller在源码根目录执行pyinstaller -w -F main.py --name StudentManager参数说明-w 表示不显示控制台窗口适合桌面程序-F 表示打包成单个 exe--name 指定生成的程序名。如果源码里使用了 .ui 文件需要在命令中追加数据文件pyinstaller -w -F main.py --name StudentManager --add-data ui/login.ui;uiWindows 下分号表示分隔Linux 和 macOS 用冒号。在代码里加载 .ui 时不能直接用相对路径否则打包后找不到文件import sys from pathlib import Path def resource_path(relative_path): base_path getattr(sys, _MEIPASS, Path(__file__).parent) return Path(base_path) / relative_path ui_path str(resource_path(ui/login.ui))sys._MEIPASS 是 PyInstaller 运行时解压临时文件的目录打包前后路径策略不同用上面的函数统一处理。6.2 qt.qpa.platform 找不到平台插件的排查解压的源码在开发环境正常打包发布到别的电脑就报错qt.qpa.platform: could not connect to display qt.qpa.plugin: Could not load the Qt platform plugin windows in 这个错误几乎都是平台插件目录缺失造成的和代码逻辑无关属于 Qt 环境变量指向错误。先检查 PyInstaller 生成的文件夹里有没有 platforms 目录里面应该有 qwindows.dll。如果用的是 PyQt5 和 PyInstaller 的常见版本只需要在 spec 文件里显式添加from PyInstaller.utils.hooks import collect_data_files qt_plugins collect_data_files(PyQt5.Qt)然后在 .spec 文件的 datas 里加入 qt_plugins。再重新打包通常能解决。另一个常见情况是开发机上装了多个 Qt 版本环境变量 QT_QPA_PLATFORM_PLUGIN_PATH 指向了不存在的 D:\qt\5.15.2\msvc2019_64\plugins运行时也出现同样报错。处理方式是在 main.py 开头强制指定插件路径import os os.environ[QT_QPA_PLATFORM_PLUGIN_PATH] os.path.join( os.path.dirname(os.path.abspath(__file__)), platforms )或者彻底一点打包时确认 platforms 文件已复制到正确位置然后把环境变量直接删掉让 PyQt5 自己去当前目录找。6.3 发布前的自检清单打包完成后按这份清单做一遍最终验证[ ] 在没有安装 Python 的机器上双击 StudentManager.exe 能启动 [ ] 登录窗口能弹出中文不显示乱码 [ ] 输入正确的账号密码能进入主界面 [ ] 添加学生后列表立即刷新 [ ] 学号重复时给出中文错误提示程序不崩溃 [ ] 删除学生时二次确认生效 [ ] 查询姓名关键字结果正确且响应快速 [ ] 关闭程序再打开新增数据还在 [ ] MySQL 服务未启动时程序给出可读的“数据库连接失败”提示最后一条经常被忽略生产环境的 MySQL 可能因为重启没自启动而连不上界面直接卡死。在数据库连接处做异常捕获给出友好的 QMessageBox 提示比黑屏终止好得多。还有一点exe 文件里是编译后的 Python 字节码理论上有反编译风险但这套组合的定位就是内部工具不是商业软件不需要引入加壳工具。如果发布时要隐藏源码PyInstaller 默认生成的是 pyc配合 upx 压缩体积系统是 Windows 的话把密码写入系统环境变量读取不要硬编码。MySQL 端记得给程序单独建一个只读或按需授权的账号避免业务系统直接使用 root 权限连接数据库。这个zip源码里改配置的地方只有 db.py 一处打包前把 host、user、password 三个参数确认清楚不容易出问题。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Matlab与Simulink在电力系统静态稳定性分析中的应用 2026/9/16 21:53:35

Matlab与Simulink在电力系统静态稳定性分析中的应用

1. 电力系统静态稳定性仿真概述电力系统静态稳定性分析是评估系统在小扰动下保持同步运行能力的关键技术。作为电力工程师,我们经常需要预测系统在负荷缓慢变化或微小故障情况下的行为特征。传统的手工计算不仅耗时费力,而且难以应对复杂网络拓扑&#x…

阅读更多 →
MagicView专业看图软件:图像管理与批量处理利器 2026/9/16 21:53:35

MagicView专业看图软件:图像管理与批量处理利器

1. MagicView 专业看图软件概述MagicView 是一款面向专业用户的图像浏览与管理工具,它突破了传统看图软件的局限,在图像渲染速度、格式兼容性和批量处理能力上都有显著提升。这款软件特别适合摄影师、设计师、医学影像工作者等需要高频处理图像的专业人士…

阅读更多 →
Velero `describe backups` 命令详解:从 Ark 到 Velero 的备份状态可视化诊断 2026/9/16 21:53:35

Velero `describe backups` 命令详解:从 Ark 到 Velero 的备份状态可视化诊断

Velero describe backups 命令详解:从 Ark 到 Velero 的备份状态可视化诊断 【免费下载链接】velero Backup and migrate Kubernetes applications and their persistent volumes 项目地址: https://gitcode.com/GitHub_Trending/ve/velero 本文聚焦 Velero&…

阅读更多 →
MCP工具自动部署实战:从Jenkins流水线到AI客户端配置同步 2026/9/16 21:53:35

MCP工具自动部署实战:从Jenkins流水线到AI客户端配置同步

最近在做内部工具链的智能化改造,接触最多的一个词就是 MCP。从 Claude 配置 MCP Server,到 Cursor 里挂各种 MCP 工具,再到团队里把 Jenkins 自动部署的能力通过 MCP 暴露给 AI Agent,一套流程跑下来,我发现真正让人头…

阅读更多 →
IBus输入法自定义实战:从运行机制到五笔拼音混合配置 2026/9/16 21:53:35

IBus输入法自定义实战:从运行机制到五笔拼音混合配置

用Linux这几年,输入法绕不开的一个东西就是IBus。不管是用Gnome桌面还是跑个轻量级窗口管理器,输入法框架大概率就是它。不少人一开始接触IBus,觉得这玩意儿就是个“能打字的输入法”,打开ibus-setup改两下就完事了。但真正用久了…

阅读更多 →
WordPress多站点部署与管理实战指南 2026/9/16 21:50:34

WordPress多站点部署与管理实战指南

1. 多站点部署的核心挑战与解决方案作为拥有十年WordPress开发经验的从业者,我经常遇到需要同时管理多个内容独立站点的需求。传统方式下,每个站点都需要单独安装、配置和维护,当站点数量超过5个时,管理成本就会呈指数级增长。最典…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞