ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

C++ Qt 学生信息管理系统实战:MySQL 驱动配置与增删改查实现

2026/9/26 7:33:33 拓冰建站 浏览量
C++ Qt 学生信息管理系统实战:MySQL 驱动配置与增删改查实现 简介这是一套面向高校计算机相关专业学生与初学者的C Qt数据库课程设计/毕业设计参考项目以MySQL为后台数据库实现学生信息管理系统。项目覆盖学生、课程、成绩、宿舍、费用、奖励等管理模块适合正在准备课程设计或想练习Qt界面与数据库交互的开发者。压缩包共79个文件约211KB其中26个cpp与25个h构成业务逻辑与类定义23个ui为Qt Designer界面文件另有pro工程文件、sql建库脚本、说明文档与运行日志结构完整、便于直接编译学习。资源已有310人学习下载可帮助读者快速理解Qt信号槽、界面布局与MySQL增删改查的整合方式并参考其模块划分与数据库表设计完成自己的课程设计或二次开发。1. 从一份能跑通的 C Qt 学生管理系统说起很多同学做毕业设计或课程设计时卡住的地方往往不是“不会写代码”而是“不知道一个完整的管理系统到底该长什么样”。这份 C Qt 基于 MySQL 的学生信息管理系统恰好就是一个能直接跑起来的完整参考。它用 Qt 做界面用 MySQL 存数据覆盖了学生、课程、成绩、宿舍、缴费、奖励等多个模块源码、SQL 脚本、说明文档一应俱全。如果你正在找一份结构清晰、模块齐全、能编译能运行的 C 课程设计或毕业设计参考这份资源值得你花时间拆一遍。它适合已经学过 C 基础、想通过一个真实项目把 Qt 和数据库串起来的人也适合需要快速搭出管理系统骨架的开发者。2. 拆开压缩包模块划分与数据库表结构怎么对应拿到压缩包后先别急着打开 Qt Creator 编译。花十分钟把目录结构和 SQL 文件过一遍后面能省下大量“编译过了但功能对不上”的返工时间。这个项目的组织方式很典型每个业务模块基本对应一组.h/.cpp/.ui文件数据库脚本单独放在studentmanager.sql里。2.1 从文件名反推功能模块把文件按前缀归类能很快看出系统边界文件前缀对应模块典型文件userlogin/insertlogin/updatelogin/deletelogin用户登录与账号管理userlogin.cpp、insertlogin.uistuinformanage/allstuinform/seeallstuinfor学生基本信息管理stuinformanage.cpp、allstuinform.uicoursemanage/coursefind课程管理与查询coursemanage.cpp、coursefind.uiscoremanage/findscore成绩录入与查询scoremanage.cpp、findscore.cppdormmanage/dormfind/seedorminfor宿舍分配与查询dormmanage.cpp、seedorminfor.uifeemanage/moneyfind缴费管理与查询feemanage.cpp、moneyfind.cppawardmanage/awardfind奖励信息管理awardmanage.cpp、awardfind.uiclassmanage/findclass班级管理classmanage.cpp、findclass.cppmanger/mainwindow主窗口与管理员入口manger.cpp、mainwindow.cppstudent/studentform学生实体与表单student.h、studentform.cppgloble全局变量与数据库连接globle.h、globle.cpp这种“一个模块一组文件”的做法在课程设计里很常见好处是职责清晰坏处是文件数量多编译时容易漏加。studenntManger.pro是 qmake 的工程文件里面列出了所有参与编译的源文件和头文件如果自己新建工程往里搬代码务必对照这个文件检查有没有遗漏。2.2 数据库表与代码的映射关系studentmanager.sql是整个系统的数据底座。导入之前先确认它建了哪些表、字段类型是否和代码里的 SQL 语句一致。常见做法是用 MySQL 命令行或 Workbench 打开这个脚本逐条看CREATE TABLE语句。-- 示例学生信息表结构以实际 SQL 文件为准 CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, gender VARCHAR(10), class_id INT, dorm_id INT, fee_status INT DEFAULT 0 );上面这段是示意实际字段名和数量以studentmanager.sql为准。重点看三件事主键是否自增、外键有没有约束、默认值是否和界面上的初始状态匹配。比如缴费状态如果默认值设成NULL而代码里判断的是0那查询就会出问题。globle.h和globle.cpp里通常放着数据库连接信息包括主机、端口、用户名、密码、库名导入 SQL 之后要同步改这里。提示导入 SQL 前先建一个空库比如student_manager字符集选utf8mb4避免中文姓名或课程名出现乱码。3. 环境搭建与工程编译Qt 版本、MySQL 驱动、qmake 配置这个项目能不能跑起来八成取决于环境对不对。Qt 和 MySQL 的版本组合、驱动加载方式、编译器套件任何一个不匹配都会报错。下面按实际操作的顺序走一遍。3.1 Qt 与 MySQL 的版本选择项目用的是 qmake 工程.pro文件不是 CMake所以 Qt 5 和 Qt 6 都能打开但建议优先用 Qt 5.14 或 Qt 5.15。原因很简单Qt 6 对某些旧版 MySQL 驱动的兼容性不如 Qt 5 稳定而且网上大量 Qt MySQL 的教程都是基于 Qt 5 的。MySQL 方面5.7 和 8.0 都可以但 8.0 的默认认证插件是caching_sha2_password老版 Qt 驱动可能连不上需要改成mysql_native_password。# 查看 MySQL 用户认证插件 SELECT user, host, plugin FROM mysql.user; # 如果 plugin 是 caching_sha2_password改成 mysql_native_password ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;这段 SQL 的作用是让 MySQL 用户使用旧版认证方式避免 Qt 的QMYSQL驱动握手失败。改完之后重启 MySQL 服务再用 Qt 连接测试。3.2 编译 MySQL 驱动或确认驱动可用Qt 默认不一定带 MySQL 驱动。打开 Qt Creator新建一个控制台测试程序只写数据库连接代码看能不能加载QMYSQL。// 测试 QMYSQL 驱动是否可用 #include QCoreApplication #include QSqlDatabase #include QSqlError #include QDebug int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() 可用驱动 QSqlDatabase::drivers(); QSqlDatabase db QSqlDatabase::addDatabase(QMYSQL); db.setHostName(127.0.0.1); db.setPort(3306); db.setDatabaseName(student_manager); db.setUserName(root); db.setPassword(你的密码); if (!db.open()) { qDebug() 连接失败 db.lastError().text(); } else { qDebug() 连接成功; } return a.exec(); }如果输出里没有QMYSQL说明驱动没编译或没放到插件目录。常见做法是找到 Qt 安装目录下的plugins/sqldrivers看有没有qsqlmysql.dllWindows或libqsqlmysql.soLinux。没有的话用 Qt 提供的mysql.pro重新编译驱动编译时需要指定 MySQL 的头文件和库路径。3.3 用 qmake 构建并解决常见链接错误回到项目本身用 Qt Creator 打开studenntManger.pro选择套件后先执行qmake再构建。如果报cannot find -lpublic或类似的库缺失检查.pro文件里的LIBS行看是否引用了本机不存在的路径。# .pro 文件中与数据库相关的典型配置 QT core gui sql greaterThan(QT_MAJOR_VERSION, 4): QT widgets # 如果手动指定 MySQL 库路径按实际安装位置改 # LIBS -LC:/Program Files/MySQL/MySQL Server 8.0/lib -llibmysql # INCLUDEPATH C:/Program Files/MySQL/MySQL Server 8.0/includeQT sql是必须的没有这行编译时找不到QSqlDatabase。如果用的是 MSVC 套件还要确保 MySQL 的lib目录在系统PATH里或者用LIBS显式指定。MinGW 套件则要注意.dll文件是否放到了可执行文件同级目录。注意编译前把构建目录清空一次避免旧的moc文件干扰。尤其是从别人机器上拷来的项目.pro.user文件里的套件路径很可能对不上删掉让它重新生成。4. 核心功能实现登录验证、学生信息增删改查、成绩与缴费联动环境通了之后重点看代码怎么把界面操作翻译成 SQL。这个项目的业务逻辑集中在各个模块的.cpp文件里套路基本一致界面收集输入 → 拼接 SQL → 执行 → 刷新表格或弹窗提示。4.1 登录模块的验证逻辑与 SQL 注入边界userlogin.cpp负责登录验证。典型写法是拿用户名和密码去user表里查查到就进主窗口查不到就提示错误。// userlogin.cpp 中登录验证的典型逻辑 void userlogin::on_loginButton_clicked() { QString username ui-usernameEdit-text().trimmed(); QString password ui-passwordEdit-text().trimmed(); QSqlQuery query; query.prepare(SELECT * FROM user WHERE username :name AND password :pwd); query.bindValue(:name, username); query.bindValue(:pwd, password); if (query.exec() query.next()) { // 登录成功打开主窗口 mainwindow *w new mainwindow(); w-show(); this-close(); } else { QMessageBox::warning(this, 登录失败, 用户名或密码错误); } }这里用了prepare和bindValue是防止 SQL 注入的正确做法。如果换成字符串拼接输入 OR 11就能绕过验证。参数说明:name和:pwd是占位符bindValue会把用户输入当作纯文本处理不会解析成 SQL 语法。query.next()判断是否有结果行有就说明账号密码匹配。4.2 学生信息模块的增删改查实现stuinformanage.cpp和allstuinform.cpp负责学生信息的录入、修改、删除和展示。以插入为例界面上的每个输入框对应表里的一个字段。// 插入学生信息的典型流程 void stuinformanage::on_addButton_clicked() { QString name ui-nameEdit-text(); QString gender ui-genderCombo-currentText(); QString classId ui-classEdit-text(); if (name.isEmpty() || classId.isEmpty()) { QMessageBox::warning(this, 提示, 姓名和班级不能为空); return; } QSqlQuery query; query.prepare(INSERT INTO student (name, gender, class_id) VALUES (:name, :gender, :class_id)); query.bindValue(:name, name); query.bindValue(:gender, gender); query.bindValue(:class_id, classId); if (query.exec()) { QMessageBox::information(this, 成功, 学生信息已添加); // 刷新表格显示 loadStudentTable(); } else { QMessageBox::critical(this, 失败, query.lastError().text()); } }逻辑说明先做非空校验避免插入脏数据然后用prepare绑定参数执行成功后调用刷新函数重新查表。参数方面class_id如果表里设了外键约束插入前要确保班级表里存在对应的id否则会报外键错误。删除操作通常用DELETE FROM student WHERE id :id修改用UPDATE student SET ... WHERE id :id套路相同。4.3 成绩、缴费、奖励模块的数据联动成绩模块scoremanage.cpp和缴费模块feemanage.cpp往往不是孤立的。比如缴费状态可能影响成绩查询权限或者奖励信息关联学生 ID。看代码时重点找JOIN语句。// 查询学生成绩并关联学生姓名 QSqlQuery query; query.prepare(SELECT s.name, c.course_name, sc.score FROM score sc JOIN student s ON sc.student_id s.id JOIN course c ON sc.course_id c.id WHERE s.class_id :class_id); query.bindValue(:class_id, classId); query.exec();这种多表关联在成绩查询、宿舍分配、奖励发放里都会出现。参数:class_id用来筛选某个班级。如果查询结果为空先检查三张表里的关联字段是否都有对应数据再检查JOIN条件有没有写错字段名。常见坑是student_id和id类型不一致一个是INT一个是VARCHARMySQL 会做隐式转换但可能不走索引。提示所有涉及金额或成绩的字段建议在数据库里用DECIMAL而不是FLOAT避免浮点误差导致缴费金额对不上。5. 避坑与排查驱动加载失败、中文乱码、界面卡死这一章记录的是实际跑这个项目时最容易翻车的地方。每条都按“现象 → 原因 → 解决”写遇到问题可以直接对照。5.1 QMYSQL 驱动加载失败现象程序启动后连接数据库报QSqlDatabase: QMYSQL driver not loaded或者available drivers列表里没有QMYSQL。原因Qt 安装时没有自带 MySQL 驱动或者驱动版本和当前 Qt 套件不匹配。Windows 上还可能是libmysql.dll没放到可执行文件目录。解决先确认plugins/sqldrivers下有没有qsqlmysql.dll。没有就用 Qt 源码里的mysql.pro编译一个编译时INCLUDEPATH指向 MySQL 的includeLIBS指向lib。编译出的qsqlmysql.dll放到sqldrivers目录libmysql.dll放到exe同级目录。Linux 下对应.so文件用ldd检查依赖是否齐全。5.2 中文乱码现象界面上显示的学生姓名、课程名变成问号或方块或者数据库里存进去的中文读出来是乱码。原因数据库、表、连接三处的字符集不一致。常见的是数据库建库时用了latin1而 Qt 这边按UTF-8发送。解决建库时指定CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。连接建立后立即执行SET NAMES utf8mb4。Qt 代码里用QString::fromUtf8和toUtf8处理字符串。如果已经建了库用ALTER DATABASE和ALTER TABLE改字符集。ALTER DATABASE student_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;5.3 界面卡死或无响应现象点击查询按钮后界面卡住过几秒才恢复数据量大时直接无响应。原因数据库查询在主线程UI 线程里同步执行查询耗时长了就会阻塞界面刷新。解决小数据量下可以接受但如果表里数据多建议把查询放到QThread或QtConcurrent::run里查完再通过信号槽把结果传回主线程更新界面。课程设计级别不强制但要知道这个边界。另一个简单做法是给查询加LIMIT避免一次性拉全表。5.4 编译时报 “cannot find -lpublic” 或类似库缺失现象链接阶段报错提示找不到某个库。原因.pro文件里LIBS引用了本机不存在的路径或者库文件名写错。解决打开.pro文件把LIBS行注释掉只保留QT sql让 Qt 自己找驱动。如果必须手动指定确认路径下的库文件确实存在Windows 下是.libLinux 下是.so。MinGW 和 MSVC 的库不通用套件选了什么就用对应的库。5.5 主窗口关闭后程序仍在后台现象关闭主窗口后任务管理器里进程还在。原因登录窗口和主窗口之间用new创建没有设置Qt::WA_DeleteOnClose或者main.cpp里return a.exec()之前有窗口没关。解决在创建主窗口时设置w-setAttribute(Qt::WA_DeleteOnClose);或者在main.cpp里用QApplication::setQuitOnLastWindowClosed(true)默认就是 true但如果有隐藏窗口就不生效。检查登录窗口关闭时是否只hide()而没有close()。6. 进阶用法把这份代码改成你自己的毕业设计直接交一份别人的代码风险很大查重和答辩都过不去。更合理的做法是把它当成骨架替换业务字段、调整界面布局、增加一两个有区分度的功能。下面说几个我常用的改造方向。6.1 替换业务字段与表结构先确定你的题目需要哪些实体。比如“实验室设备管理系统”就把student表改成device表字段从姓名、性别、班级换成设备名、型号、采购日期。对应的.cpp文件里 SQL 语句和界面标签同步改。改的时候用全局搜索替换但注意student_id这种外键字段名不要漏改否则JOIN会断。-- 把学生表改造成设备表的示例 RENAME TABLE student TO device; ALTER TABLE device CHANGE name device_name VARCHAR(100); ALTER TABLE device CHANGE class_id lab_id INT; ALTER TABLE device ADD COLUMN purchase_date DATE;改完表结构后把globle.h里的表名宏定义也改掉避免硬编码散落各处。6.2 增加一个统计图表模块答辩时有个图表会加分不少。Qt 自带QtCharts模块可以在主窗口加一个“统计”按钮点击后弹出一个窗口用柱状图显示各班级人数或各课程平均分。// 使用 QtCharts 画一个简单柱状图 #include QtCharts/QChartView #include QtCharts/QBarSeries #include QtCharts/QBarSet #include QtCharts/QBarCategoryAxis void statisticWindow::showChart() { QBarSet *set new QBarSet(人数); *set 30 25 28 22; // 各班级人数实际从数据库查 QBarSeries *series new QBarSeries(); series-append(set); QChart *chart new QChart(); chart-addSeries(series); chart-setTitle(各班级人数统计); QStringList categories; categories 一班 二班 三班 四班; QBarCategoryAxis *axisX new QBarCategoryAxis(); axisX-append(categories); chart-addAxis(axisX, Qt::AlignBottom); series-attachAxis(axisX); QChartView *view new QChartView(chart); view-setRenderHint(QPainter::Antialiasing); view-resize(600, 400); view-show(); }这段代码的关键是QBarSet存数据、QBarSeries做系列、QChart管标题和坐标轴。数据不要写死从数据库SELECT class_id, COUNT(*) FROM student GROUP BY class_id查出来再填进去。.pro文件里要加QT charts。6.3 用事务保证多表操作一致性删除一个学生时如果他的成绩、缴费、奖励记录还留在其他表里就会产生孤儿数据。正确做法是用事务包起来。QSqlDatabase::database().transaction(); QSqlQuery query; query.prepare(DELETE FROM score WHERE student_id :id); query.bindValue(:id, studentId); bool ok1 query.exec(); query.prepare(DELETE FROM fee WHERE student_id :id); query.bindValue(:id, studentId); bool ok2 query.exec(); query.prepare(DELETE FROM student WHERE id :id); query.bindValue(:id, studentId); bool ok3 query.exec(); if (ok1 ok2 ok3) { QSqlDatabase::database().commit(); } else { QSqlDatabase::database().rollback(); QMessageBox::critical(this, 错误, 删除失败已回滚); }事务的好处是任何一步失败前面的删除都会撤销不会留下半截数据。参数:id是学生主键三张表都用同一个值。注意 MySQL 的 InnoDB 引擎才支持事务MyISAM 不支持建表时确认引擎类型。6.4 打包发布时带上 MySQL 依赖最后交作品时不能要求老师电脑上装 Qt 和 MySQL。用windeployqt把 Qt 依赖拷出来再把libmysql.dll和sqldrivers目录一起放进去。数据库可以用 SQL 脚本在目标机器上先导入或者改用 SQLite 做单机演示版把QMYSQL换成QSQLITE连接字符串改成文件路径即可。SQLite 不需要额外安装服务适合答辩现场演示。// 切换到 SQLite 做单机演示 QSqlDatabase db QSqlDatabase::addDatabase(QSQLITE); db.setDatabaseName(student_manager.db);改完之后所有 SQL 语句基本不用动但要注意 SQLite 不支持RIGHT JOIN和某些 MySQL 函数遇到报错就改成子查询或分步查询。从那以后我每次拿到别人的课程设计代码都先跑通数据库连接再动界面不然改了半天发现驱动没加载时间全白费。希望帮到你。本文还有配套的精品资源点击获取