ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

QT+MySQL垃圾分类查询系统源码:课程设计完整工程与避坑指南

QT+MySQL垃圾分类查询系统源码:课程设计完整工程与避坑指南 简介这是一套基于Qt与MySQL搭建的垃圾分类查询系统完整源码面向计算机相关专业学生及企业开发者可作为课程设计、大作业、毕业设计或初期项目立项的实战参考。项目实现垃圾信息录入、查询、修改与删除等核心功能并配有可回收物、有害垃圾、湿垃圾、干垃圾等分类图标资源界面通过QSS样式表美化支持跨平台运行。压缩包共46个文件约109KB包含8个cpp源文件与7个h头文件构成业务逻辑6个ui界面文件与4个qss样式文件负责交互与视觉呈现另有qrc资源文件、pro工程文件及README说明文档结构清晰便于二次开发。目前已有95人学习下载。读者可从中掌握Qt界面布局、信号槽机制、MySQL数据库连接与增删改查操作以及多主题样式切换的实现思路适合作为入门练手与项目答辩的参考范例。1. 从一次课程设计翻车说起这套 QTMySQL 垃圾分类查询系统到底能干什么去年带一个课程设计小组选题是“垃圾分类查询系统”几个同学用 Python Tkinter 写了一版界面丑到没法演示查询逻辑还是硬编码在列表里导师看了一眼就说“这不像一个完整的软件工程产物”。后来换了一套基于 QTMySQL 的源码编译运行之后增删改查、分类浏览、样式切换全都有答辩时直接被当作范本展示。这套基于QTmysql搭建的垃圾分类查询系统源码项目说明.zip就是那类“能跑、能改、能交差”的完整工程不是那种只有几个界面文件的半成品。它解决的核心问题很具体把垃圾分类数据从静态文本变成可维护的数据库记录再用 QT 做一套带交互的桌面客户端。适合计算机相关专业的课程大作业、毕业设计初期原型也适合想练手 QT 数据库编程的开发者。源码里包含了garbage-query.pro、mainwindow.cpp、garbageinfo.cpp、query.cpp、addgarbage.cpp、modify.cpp、deletegarbage.cpp等完整模块还有garbage.txt作为初始数据、多套.qss样式文件、图片资源和.ui界面文件。拿到手之后你面对的不是一个黑匣子而是一个可以逐行拆解的 C 桌面项目。2. 工程结构与数据流先看清 QT 项目怎么把 MySQL 接进来2.1 从.pro到.ui文件清单背后的模块划分拿到压缩包解压后根目录下会看到garbage-query.pro这是 qmake 的工程文件决定了编译时链接哪些库、包含哪些源文件。和它同级的main.cpp是程序入口mainwindow.h/.cpp/.ui是主窗口负责整体布局和菜单切换。menuwidge.h/.cpp/.ui是侧边或顶部导航组件query、addgarbage、modify、deletegarbage、garbageinfo各自成对出现分别对应查询、添加、修改、删除和垃圾分类信息展示五个功能页。资源方面image.qrc是 QT 的资源集合文件把image/目录下的cquery.png、browse.png、modify.png、add.png、delete.png、可回收物.png、有害垃圾.png、湿垃圾.png、干垃圾.png等图标打包进可执行文件避免运行时找不到图片。garbage.txt是初始数据文本通常用来在数据库为空时导入基础分类记录。style.qss、ElegantDark.qss、Ubuntu.qss、MacOS.qss是不同风格的样式表通过菜单或配置切换界面外观。文件/目录作用是否必须保留garbage-query.proqmake 工程配置链接 MySQL 驱动是mainwindow.*主窗口框架承载页面切换是query.*/addgarbage.*/modify.*/deletegarbage.*增删改查四个功能页是garbageinfo.*垃圾分类详情展示是menuwidge.*导航菜单组件是image.qrcimage/图标与分类图片资源是*.qss界面样式可替换否但建议保留garbage.txt初始数据用于建库后导入建议保留这个划分方式很典型一个主窗口 多个功能页 一个导航组件每个功能页独立成类通过信号槽和主窗口通信。你如果要加一个新功能比如“批量导入”就照着addgarbage复制一套改类名和界面再在主窗口里注册一下。2.2 MySQL 连接与数据表设计别让驱动成为第一道坎QT 连接 MySQL 靠的是QSqlDatabase但前提是 QT 编译时带了 MySQL 驱动或者你手动编译了qsqlmysql插件。源码里通常会在mainwindow.cpp或单独的数据库工具类里写连接逻辑常见写法是// 在 mainwindow.cpp 或独立的 dbhelper.cpp 中 QSqlDatabase db QSqlDatabase::addDatabase(QMYSQL); db.setHostName(127.0.0.1); // 数据库地址本机就写回环地址 db.setPort(3306); // MySQL 默认端口 db.setDatabaseName(garbage_db); // 数据库名需提前建好 db.setUserName(root); // 用户名按实际改 db.setPassword(123456); // 密码按实际改 if (!db.open()) { QMessageBox::critical(this, 连接失败, db.lastError().text()); return; }这段代码的逻辑很直白先注册 MySQL 驱动再设置主机、端口、库名、账号密码最后open()。如果失败用lastError().text()把具体错误弹出来而不是只提示“连接失败”。参数说明setHostName填数据库所在机器本机开发就写127.0.0.1setDatabaseName必须和你在 MySQL 里CREATE DATABASE的名字一致setUserName和setPassword按你本地 MySQL 的配置来不要照抄。数据表一般至少两张一张存垃圾条目一张存分类。常见建表语句如下-- 分类表 CREATE TABLE category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL ); -- 垃圾条目表 CREATE TABLE garbage ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, category_id INT, description TEXT, FOREIGN KEY (category_id) REFERENCES category(id) );category表存“可回收物、有害垃圾、湿垃圾、干垃圾”四类garbage表存具体垃圾名称和描述通过category_id关联。查询时用JOIN把分类名带出来界面上就能显示“电池 → 有害垃圾”这样的结果。如果你把garbage.txt里的数据导入注意文本编码用 UTF-8否则中文会变问号。提示QT 的 MySQL 驱动不是默认就有的如果QSqlDatabase::drivers()里没有QMYSQL需要自己编译驱动插件或者换用QSQLITE先跑通逻辑再换回 MySQL。3. 编译运行与功能验证从零把项目跑起来的完整步骤3.1 环境准备与 qmake 编译这套源码是 qmake 工程不是 CMake所以用 QT Creator 打开garbage-query.pro最省事。环境上需要QT 5.x建议 5.12 以上、MySQL 5.7 或 8.0、对应版本的 MySQL 驱动。如果你用的是 QT 5.15 自带 MinGW 编译套件MySQL 驱动可能需要单独处理这是第一个容易翻车的地方。编译步骤# 1. 用 QT Creator 打开 garbage-query.pro # 2. 选择构建套件Kit比如 Desktop Qt 5.15.2 MinGW 64-bit # 3. 在项目设置里确认 MySQL 库路径已加入 # 4. 点击“构建”按钮或命令行执行 qmake garbage-query.pro make # Linux/macOS mingw32-make # Windows MinGW如果编译报错“undefined reference tomysql_init”之类说明链接器找不到 MySQL 客户端库。需要在.pro文件里加LIBS -L/usr/lib/x86_64-linux-gnu -lmysqlclient INCLUDEPATH /usr/include/mysqlWindows 下路径换成你 MySQL 安装目录下的lib和include。这一步没有统一答案因为每个人 MySQL 装的位置不一样但思路就是告诉 qmake 去哪里找头文件和库文件。3.2 建库、导数据与界面功能走查编译通过后先别急着点运行先把数据库准备好。用 MySQL 命令行或图形工具执行CREATE DATABASE garbage_db DEFAULT CHARACTER SET utf8mb4; USE garbage_db; -- 然后执行上面提到的建表语句 -- 再把 garbage.txt 里的数据整理成 INSERT 语句导入garbage.txt的格式通常是每行“垃圾名称,分类,描述”或者类似结构导入前先看一眼分隔符。如果它本身就是 SQL 插入语句直接source garbage.txt即可如果是纯文本写个简单的 Python 脚本转成INSERT# 将 garbage.txt 转为 SQL 插入语句 with open(garbage.txt, r, encodingutf-8) as f: lines f.readlines() with open(import.sql, w, encodingutf-8) as out: for line in lines: parts line.strip().split(,) if len(parts) 2: name, category parts[0], parts[1] desc parts[2] if len(parts) 2 else out.write(fINSERT INTO garbage (name, category_id, description) fSELECT {name}, id, {desc} FROM category WHERE name{category};\n)这段脚本按逗号切分第一列是垃圾名第二列是分类名第三列是描述。INSERT ... SELECT的写法是为了根据分类名动态取category_id避免手动查 ID。导入后运行程序依次点“查询”“添加”“修改”“删除”确认每个页面都能正常读写数据库。查询页一般支持按名称模糊搜索添加页要校验空值修改页要先选中再改删除页要有二次确认。这些交互细节在query.cpp、addgarbage.cpp里都能找到对应实现。注意如果界面中文显示乱码检查源文件编码和数据库连接字符集通常在连接后执行SET NAMES utf8mb4可以解决。4. 避坑与排查这套源码最容易卡住的五个地方4.1 驱动加载失败QMYSQL driver not loaded现象程序启动后弹窗提示“QMYSQL driver not loaded”或者QSqlDatabase::drivers()输出里没有QMYSQL。原因通常是 QT 安装时没有编译 MySQL 驱动插件或者插件路径不对。解决先确认 QT 安装目录下plugins/sqldrivers/里有没有qsqlmysql.dllWindows或libqsqlmysql.soLinux。如果没有需要手动编译驱动或者改用QSQLITE先把业务逻辑跑通再回头处理 MySQL 驱动。4.2 编译时报 MySQL 头文件找不到现象fatal error: mysql.h: No such file or directory。原因.pro里没有加INCLUDEPATH或者 MySQL 开发包没装。解决Linux 下装libmysqlclient-devWindows 下确认 MySQL 安装目录下有include文件夹然后在.pro里补上路径。路径不要写死成别人的机器用相对路径或环境变量更稳。4.3 增删改查操作后界面不刷新现象添加一条记录后查询页还是旧数据删除后列表里还在。原因QT 的QSqlTableModel或QSqlQueryModel没有重新select()或者用了QSqlQuery执行后没有同步模型。解决在每次增删改之后调用model-select()重新查询或者用QSqlTableModel::submitAll()并检查返回值。如果用的是自定义QSqlQuery记得在exec()之后把结果重新绑定到界面控件。4.4 中文乱码数据库里是问号界面显示方块现象插入“电池”变成“??”或者界面显示“锟斤拷”。原因数据库、表、连接三处字符集不一致。解决建库时用utf8mb4建表时指定DEFAULT CHARSETutf8mb4QT 连接后执行query.exec(SET NAMES utf8mb4)。另外确认源文件保存为 UTF-8 无 BOMQT Creator 默认就是 UTF-8但 Windows 下用记事本改过就可能变。4.5 样式表加载后界面错乱现象换了ElegantDark.qss之后按钮文字看不清或者布局挤在一起。原因样式表里的选择器太宽泛或者和.ui文件里的内联样式冲突。解决先注释掉.qss里的全局*选择器只针对具体控件类设置检查.ui里有没有手动设置styleSheet属性有的话会覆盖外部样式表。调试时可以用qApp-setStyleSheet()临时清空确认问题来源。5. 二次开发与数据验证把课程设计变成能讲清楚的项目5.1 加一个“批量导入”功能页如果你想让这个项目在答辩时更有亮点加一个批量导入页是最划算的。照着addgarbage复制一套文件改类名为BatchImport界面放一个QTextEdit和一个“导入”按钮。核心逻辑是逐行解析文本拼成INSERT语句用事务提交// batchimport.cpp 中的导入槽函数 void BatchImport::onImportClicked() { QString text ui-textEdit-toPlainText(); QStringList lines text.split(\n, Qt::SkipEmptyParts); QSqlQuery query; query.exec(START TRANSACTION); // 开启事务提升批量插入速度 for (const QString line : lines) { QStringList parts line.split(,); if (parts.size() 2) continue; query.prepare(INSERT INTO garbage (name, category_id, description) SELECT ?, id, ? FROM category WHERE name ?); query.addBindValue(parts[0].trimmed()); query.addBindValue(parts.size() 2 ? parts[2].trimmed() : ); query.addBindValue(parts[1].trimmed()); if (!query.exec()) { qDebug() 插入失败: query.lastError().text(); } } query.exec(COMMIT); // 提交事务 QMessageBox::information(this, 完成, 批量导入结束); }START TRANSACTION和COMMIT把多条插入包成一个事务比逐条提交快很多。prepareaddBindValue是参数化查询能防止引号导致的 SQL 错误也避免注入。SELECT ... FROM category WHERE name ?是为了根据分类名拿id如果分类名写错这条插入就会失败但不会影响其他行。导入完成后记得在主窗口的导航里加上这个新页面的入口。5.2 用 SQL 直接验证数据一致性界面操作多了之后数据可能对不上。与其在界面上反复点不如直接查数据库-- 检查有没有垃圾条目关联了不存在的分类 SELECT g.id, g.name, g.category_id FROM garbage g LEFT JOIN category c ON g.category_id c.id WHERE c.id IS NULL; -- 统计每个分类下的垃圾数量 SELECT c.name, COUNT(g.id) AS total FROM category c LEFT JOIN garbage g ON g.category_id c.id GROUP BY c.id, c.name;第一条查孤儿记录第二条看分类分布。如果第一条有结果说明category_id指向了已删除的分类界面上可能显示空白分类名。第二条能帮你确认数据导入是否完整比如“有害垃圾”下面只有两三条那可能是garbage.txt没导全。这种验证方式比在界面上翻页快得多也适合在答辩时展示你对数据完整性的理解。5.3 样式切换与打包发布源码里带了四套.qss你可以在主窗口加一个下拉框读取:/styles/下的文件并qApp-setStyleSheet()。打包发布时Windows 下用windeployqt把 QT 依赖库拷到可执行文件旁边Linux 下用linuxdeployqt或手动整理.so。MySQL 驱动插件也要一起带上否则换台机器就报“driver not loaded”。我一般会在发布前把数据库连接信息抽到一个config.ini里避免硬编码密码也方便别人改。从那以后我每次拿到这类 QTMySQL 的课程设计源码都先跑一遍QSqlDatabase::drivers()确认驱动再建库导数据最后才动界面。这套流程走下来基本不会在答辩现场翻车。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进