ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Qt C++校园商铺系统源码运行与调试全流程指南

Qt C++校园商铺系统源码运行与调试全流程指南 简介一套基于Qt与C的校园商铺管理系统源码及开发指南定位面向毕业设计、课程实践与希望掌握桌面应用开发的进阶学习者。系统覆盖登录验证、购物车、管理员管理、文件上传、用户信息维护、充值、消息处理等核心模块模块划分清晰便于按需研读和扩展功能。压缩包共140个文件约15.66MB其中以cpp/h源码、ui界面文件、qrc资源、png/jpg图片素材为主工程文件齐全可导入Qt Creator直接编译运行适合快速搭建起可演示的商铺管理原型便于对照源码逐一调试。资源包另附license说明便于确认学习与二次开发的使用边界目前已有30人学习下载亦可用于小组协作或课堂实训。通过研读主窗口、购物车等关键模块的实现可以理解Qt信号槽机制、界面与业务逻辑分离的常见做法还能借鉴登录鉴权、数据持久化、文件上传等功能的编码思路帮助完成从功能模仿到独立创新的过渡是毕业设计或高校课程设计值得参考的完整示例。1. QtC实现的校园商铺系统源码及开发指南到手先能跑才算入门QtC实现的校园商铺系统是课程设计和简历项目里出现频率很高的一个选题用户能注册登录、浏览商品、加购物车、下单管理员能维护商品和订单。这类源码包难点不在代码量而在于拿到手之后能不能在你自己的机器上跑通——Qt版本、编译器、数据库驱动、中文字体任何一个环节不对工程就会吐出一堆读不懂的报错。这篇开发指南按我实际调试课设源码的顺序来写先拆系统结构和数据表再给一套在Windows或Linux上可复现的构建配置然后落到登录、商品列表、下单这几段核心代码最后是高频报错与排错手法。适合要交课程设计或毕设的学生也适合刚学完C想找一个带界面、带数据库的完整项目来练手的从业者。读完你能判断一套源码值不值得改以及怎么改成自己的。2. 校园商铺系统先拆结构角色、页面、数据表和源码目录拿到任何一份源码先做的不是编译而是搞清楚它到底由哪几个窗口、哪几张表组成。校园商铺系统这类课设源码结构高度相似无非是三类角色、三类页面、五六张表。你先把这个骨架画出来后续所有编译报错和业务代码都能对号入座而不是看到报错就去翻几百行的mainwindow.cpp。2.1 三类角色对应三类界面主窗口用QStackedWidget切换页面一条典型链路是登录窗口提交账号密码成功后进主窗口主窗口根据角色切换不同页面。普通用户看商品、购物车和我的订单商户看重自己的商品和订单管理员看全部用户和整体订单状态。很多源码把每个页面做成独立QDialog登录后按角色new出来。能跑但有两个长期毛病每个窗口要各维护一份“当前登录用户”状态改密码、改昵称时要到处通知窗口之间信号槽连得复杂后期加需求容易动一发而牵全身。我见过的成熟课设写法是MainWindow里放一个QStackedWidget商品页、购物车页、订单页、商户库存页都作为子页面注册进去再定义一个结构体保存当前登录用户信息登录成功后把这个结构体以const引用传进主窗口。struct UserInfo { int userId -1; // -1 表示未登录 QString username; int role 0; // 0普通用户 1商户 2管理员 QString nickname; // 界面欢迎语用 };这段结构体就是整个系统的“登录态”。userId为-1表示匿名状态role决定QStackedWidget切到哪一页nickname用于主窗口右上角的欢迎语。为什么要用结构体而不是七八个全局变量因为商品页要显示昵称购物车页要知道userId结算页要同时读userId和role。统一传一个UserInfo指针比散落着一堆全局单例好排查得多角色切换也只判断role一个字段而不是分别判断is_admin、is_seller、is_user三个bool。ui-stackedWidget-setCurrentWidget(ui-shopPage); // 普通用户进商品页 ui-stackedWidget-setCurrentWidget(ui-adminPage); // 管理员进用户管理页setCurrentWidget的参数必须是构造函数里addWidget注册过的页面对象。如果源码里用的是setCurrentIndex逻辑等价但要先读构造函数里addWidget的顺序才能看懂。还有一类源码是每个角色一个独立MainWindow登录成功后关掉登录窗口再new MainWindow功能上没问题只是主窗口之间要互相传用户身份改起来成本高一截。拿到这类源码想重构第一步就是把三套页面统一收进一个QStackedWidget。2.2 数据表设计SQLite起步字段别拍脑袋课程设计和绝大多数内部演示系统SQLite就够了单文件、免安装、Qt自带QSQLITE驱动把整个工程拷到另一台机器也能跑。MySQL要单独配驱动和连接参数很多人第一次跑就挂在driver not loaded上。校园商铺这种量级SQLite不会成为性能瓶颈以后真需要换MySQL把QSqlQuery的调用层换掉SQL语句基本不用动。校园商铺系统的表大致就三张核心表先看字段清单表字段类型/单位说明goodsidINTEGER主键自增goodsnameTEXT商品名goodspriceINTEGER单价单位分goodsstockINTEGER库存goodsseller_idINTEGER归属商户IDgoodsstatusINTEGER1上架 / 0下架ordersorder_noTEXT订单号ordersuser_idINTEGER下单用户IDorderstotal_amountINTEGER总价单位分ordersstatusINTEGER0待付款 1已付款 2已发货 3已完成 4已取消order_itemsgoods_nameTEXT商品名快照order_itemspriceINTEGER单价快照order_itemscountINTEGER数量注意两个字段设计习惯。第一金额用整数分存储显示时除以100避免double在累计相加时的浮点误差——这是一个答辩时容易被老师注意到的小亮点。第二订单明细表里要有goods_name和price快照因为商户改价改名后历史订单不应该跟着变源码里如果直接JOIN商品表显示历史订单就是这个字段设计没过关。CREATE TABLE IF NOT EXISTS goods ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, price INTEGER NOT NULL DEFAULT 0, stock INTEGER NOT NULL DEFAULT 0, seller_id INTEGER NOT NULL, status INTEGER NOT NULL DEFAULT 1, image_path TEXT DEFAULT );建表SQL里最重要的就是IF NOT EXISTS。登录窗口一启动可能就调用initDatabase()重复执行不会报错缺了这个第二次运行就会因table already exists崩溃。SQLite连接建立后建议顺手执行PRAGMA encoding UTF-8;否则后面读出来的中文可能乱码。2.3 源码目录怎么认main.cpp是入口不要在.ui里迷路一个典型的Qt工程打开后有这些文件main.cpp、mainwindow.ui、mainwindow.cpp、loginwindow.cpp、shopwidget.cpp或类似页面类、database.cpp和database.h、resources.qrc资源文件。初学者最常见的动作是双击ui文件看界面这解决不了逻辑问题。按下面顺序读链路最顺先main.cpp看哪些模块被初始化再database.cpp看表结构在哪里建最后找一个按钮的槽函数比如登录按钮看界面怎么和数据库连起来。#include QApplication #include QFont #include loginwindow.h int main(int argc, char *argv[]) { QApplication a(argc, argv); QFont font(Microsoft YaHei, 9); // 中文界面字体 a.setFont(font); LoginWindow w; w.show(); return a.exec(); }这个入口信息量很大设置了微软雅黑说明作者考虑过中文显示入口是LoginWindow而不是MainWindow说明登录成功后主窗口才被创建。如果main里直接new MainWindow那登录窗口大概率是在主窗口内部用模态对话框模拟的功能没问题但链路更绕排查登录问题时要点进MainWindow的构造函数。然后是构建文件。老式工程用.pro新工程用CMakeLists.txt。看这个文件能直接暴露源码依赖了Qt哪些模块cmake_minimum_required(VERSION 3.16) project(school_shop CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) find_package(Qt5 REQUIRED COMPONENTS Widgets Sql) add_executable(school_shop main.cpp loginwindow.cpp loginwindow.h mainwindow.cpp mainwindow.h database.cpp database.h ) target_link_libraries(school_shop PRIVATE Qt5::Widgets Qt5::Sql)AUTOUIC、AUTOMOC、AUTORCC这三个变量必须开着否则ui头文件、信号槽元对象代码、qrc资源都不会被编译进目标链接阶段会报一堆莫明其妙的未定义引用。target_link_libraries里没有Qt5::Network说明这个系统是纯本地演示没走HTTP请求——课设源码绝大多数就是本地SQLite直连不需要服务器。如果拿到的是.pro文件逻辑等价QT core gui sql widgets TARGET school_shop TEMPLATE app SOURCES main.cpp loginwindow.cpp mainwindow.cpp database.cpp HEADERS loginwindow.h mainwindow.h database.h userinfo.hqmake里QT sql就是启用SQL模块。缺了它所有QSqlQuery相关的编译都会报no such file这是qmake工程最常见的配置错位。3. 源码本地跑通Qt版本、编译器与构建参数怎么选我陪别人跑课设源码时结论八成是环境问题而不是代码问题。拿到源码后先别急确认三件事Qt版本、编译器、构建方式。这三个参数定下来剩下就是点击构建的事参数定错后面每一条编译报错都在浪费你的时间。3.1 MinGW还是MSVC这个选择决定你要不要折腾一晚上Windows上跑Qt源码第一道分岔就是编译器。Qt安装时提供的套件里常见有MinGW 64-bit和MSVC 2019 64-bit两套。前者是GCC在Windows上的移植版Qt Creator装完自带编译器不用另外装Visual Studio后者是微软的C编译器必须配合Visual Studio的“使用C的桌面开发”组件或单独的Build Tools才能用。对比下来差异很明确维度MinGWMSVC编译器来源Qt自带GCC系微软官方需VS组件调试器GDBCreator集成好CDBWindows下成熟第三方库兼容部分库只发MSVC版兼容性最好课设源码适配上手快依赖路径容易报错典型报错缺libstdcdependent找不到VS include我的建议很直接在Windows上跑课程设计源码优先MinGW 64位不用额外装Visual Studio拿到一个.pro就能编译。如果源码或第三方库明确要求MSVC再切过去。Linux下没有这个纠结系统gcc加上Qt的linux kit一条路走到底。3.2 Qt版本怎么定Qt 5.15.2还是Qt 6.x版本选择看源码里的API线索。源码里出现QRegExp、QTextCodec、QString::SkipEmptyParts这些说明是Qt5风格配Qt 5.15.2 LTS最稳这也是网上课设源码存量最大的版本如果源码用的是QRegularExpression、QStringView、setContentsMargins这类写法Qt 6.5之后也没问题。安装包有一个常见获取渠道是清华镜像Qt 5.15.2和6.x的安装器都有归档下载速度快不依赖外部网络。安装时记得把对应版本的源码勾上Qt Creator跳转到符号定义时会用到否则定位不到Qt库内部实现排查信号槽问题会很吃力。提示同一台机器可以同时装MinGW和MSVC两套Kit但构建目录一定分开。Release和Debug构建目录也要分开两个配置来回切换会让Qt Creator的增量编译失效。3.3 在Qt Creator里导入源码四步构建配置拿到.pro或CMakeLists.txt后打开Qt Creator选择打开项目定位到该文件。接下来的步骤顺序不要乱先选Kit再设置构建目录然后构建最后运行。Kits里能看到Qt 5.15.2 MinGW 64-bit和Qt 5.15.2 MSVC2019 64-bit两组选项选哪个和3.1的结论对应起来。如果列表里没有Kit说明安装Qt时没勾选对应编译器重跑安装器勾上即可不要在工具菜单里手动乱指路径容易把qmake和编译器配成两套体系。如果源码是CMake工程Qt Creator会自动套用默认参数。需要手动指定Qt安装位置时在命令行或CMake配置面板里加cmake -S . -B build -DCMAKE_BUILD_TYPERelease -DCMAKE_PREFIX_PATHC:/Qt/5.15.2/mingw81_64 cmake --build build -j 4-S和-B是CMake的规范化写法-S指定源码目录-B指定构建目录。CMAKE_PREFIX_PATH的作用是告诉CMake到哪里找Qt5Config.cmake这个路径不对最典型的报错是Could not find a package configuration file provided by Qt5。构建参数里的-j 4是并行编译任务数按CPU线程取8核机器可以设-j8编译中等规模Qt工程会明显变快。qmake工程走另一组命令qmake school_shop.pro -spec win32-g CONFIGrelease mingw32-make -j4-space win32-g让qmake按MinGW方式生成Makefile。如果你误用了MSVC的spec后面mingw32-make会报一堆语法不认识的错误。CONFIGrelease指定构建配置要编译调试版就去掉这一条。3.4 编译通过却闪退动态库与插件要跟上最让人搓败的不是编译失败而是编译过了运行窗口闪一下就没。此时Qt Creator的“应用程序输出”面板通常有句话This application failed to start because no Qt platform plugin could be initialized。这代表exe在启动时找不到Qt平台插件Windows下是plugins/platforms/qwindows.dll。原因就两类一是直接双击了build目录下的exe它和Qt的库目录分离二是数据库插件qsqlite.dll没在plugins/sqldrivers里登录界面还没起来就崩。常见做法是把Qt运行库拷到exe旁边Windows下用windeployqt一行命令处理cd build C:/Qt/5.15.2/mingw81_64/bin/windeployqt.exe school_shop.exe这个工具会扫描exe依赖的Qt模块把对应的dll和plugins目录拷贝到exe同一目录。执行后目录里会出现platforms和sqldrivers两个子目录少了任何一个都会出闪退问题。分发课程设计时把整个build目录连同exe拷走换一台机器通常能直接运行。Linux下思路一样用软件包管理装好Qt平台插件常见的坑是缺libxcb-cursor0装上即可。4. 从登录到下单校园商铺系统三段核心代码的落地姿势环境跑通后再回头读业务代码你会发现校园商铺系统的重头戏就三段登录验证、商品列表展示、购物车下单。这三段覆盖了Qt最常用的三个能力QSqlQuery查库、QStandardItemModel填表、QSqlDatabase事务。下面给出的是这类系统里的标准写法参数和坑都标出来。4.1 登录验证prepare绑定代替字符串拼接登录逻辑的第一条线是查询用户第二条线是防止被人把SQL语句改掉。课程设计源码里常见写法是SELECT * FROM users WHERE username admin AND password 123把用户输入直接拼进SQL。用户名输入个admin --就能绕过密码判断属于答辩时一定会被问到的安全点。规范写法是prepare绑定参数bool Database::login(const QString username, const QString password, UserInfo info) { QSqlQuery query(m_db); query.prepare(SELECT id, username, role, nickname FROM users WHERE username ? AND password ?); query.addBindValue(username); query.addBindValue(password); if (!query.exec()) { qWarning() login query failed: query.lastError().text(); return false; } if (query.next()) { info.userId query.value(0).toInt(); info.username query.value(1).toString(); info.role query.value(2).toInt(); info.nickname query.value(3).toString(); return true; } return false; }prepare加addBindValue的好处是参数由驱动转义用户名里的单引号不会破坏SQL结构。password存明文在真实系统是问题但课设演示场景几乎都这么写想让答辩加分可以加一层QCryptographicHash做SHA-256属于扩展项。返回值这里简化为bool更完整的做法是定义错误枚举区分“网络错误”和“密码错误”但现在写qWarning日志已经够排错用。登录按钮的槽函数组织方式更关键void LoginWindow::onLoginClicked() { UserInfo info; if (!m_db.login(ui-editUser-text(), ui-editPass-text(), info)) { QMessageBox::warning(this, 登录失败, 用户名或密码错误); return; } auto *mainWin new MainWindow(info, m_db); mainWin-show(); this-close(); }MainWindow构造函数接收UserInfo和Database引用把登录态和数据库连接交给主窗口。这里用new而不用栈对象是因为主窗口要在登录窗口销毁之后继续存活。凡是登录成功后立刻“跳回登录页”的翻车现场多半是把主窗口变量放在了局部作用域里函数一退出窗口就被销毁。4.2 商品列表QTableView配QStandardItemModel从源头避开刷新和卡顿商品列表是校园商铺里被点次数最多的界面。初学者容易用QListWidget一行行addItem商品只有几十条时看不出问题一旦加了搜索、按价格排序、分页或者商品库存表变成上千条就开始卡。而QTableView配model天然支持列宽调整、排序和选择模型所以这类系统里最常见的正确选择是QTableView加QStandardItemModel。void ShopWidget::refreshGoods(int sellerId) { m_model-clear(); // 先清空旧数据 m_model-setHorizontalHeaderLabels({商品, 价格, 库存, 状态}); QSqlQuery query(m_db); query.prepare(SELECT name, price, stock, status FROM goods WHERE seller_id ? ORDER BY id); query.addBindValue(sellerId); int row 0; while (query.next()) { m_model-setItem(row, 0, new QStandardItem(query.value(0).toString())); double yuan query.value(1).toInt() / 100.0; m_model-setItem(row, 1, new QStandardItem(QString::number(yuan, f, 2))); m_model-setItem(row, 2, new QStandardItem(query.value(2).toString())); m_model-setItem(row, 3, new QStandardItem(query.value(3).toInt() 1 ? 上架 : 下架)); row; } m_model-setRowCount(row); }先clear再setHorizontalHeaderLabels否则上一次查询的旧行还留在表里刷新后列表越叠越多。setRowCount(row)强制按实际行数收尾这是和“QTableView只显示几十行”最相关的一个习惯model行数没设置正确视图就认为没数据可显示。价格在数据库里是整数分这里除以100转元用f,2保留两位小数。status字段转成“上架/下架”可读文本而不是显示0和1。QStandardItemModel适合中小数据量胜在API简单数据量到几千行以后再换QAbstractTableModel按需取数。一开始就上自定义model新手会在data()、rowCount()、headerData()的契约里挣扎很久课设这个体量不值得。4.3 下单流程事务把订单、明细、库存绑在一起下单时需要同时做三件事写orders表、写order_items表、扣goods.stock。这三件事任何一个失败都应该整体回滚。只commit不rollback的源码订单写了一半、库存扣了一半属于必须改的硬伤bool Database::createOrder(int userId, const QVectorCartItem items, QString errMsg) { QSqlDatabase db QSqlDatabase::database(); if (!db.transaction()) { errMsg 无法开启事务; return false; } QSqlQuery q(db); q.prepare(INSERT INTO orders (order_no, user_id, total_amount, status, create_time) VALUES (?, ?, ?, 0, datetime(now))); q.addBindValue(generateOrderNo()); q.addBindValue(userId); q.addBindValue(computeTotal(items)); if (!q.exec()) { db.rollback(); errMsg q.lastError().text(); return false; } int orderId q.lastInsertId().toInt(); for (const CartItem item : items) { QSqlQuery detail(db); detail.prepare(INSERT INTO order_items (order_id, goods_id, goods_name, price, count) VALUES (?, ?, ?, ?, ?)); detail.addBindValue(orderId); detail.addBindValue(item.goodsId); detail.addBindValue(item.name); detail.addBindValue(item.price); detail.addBindValue(item.count); if (!detail.exec()) { db.rollback(); errMsg detail.lastError().text(); return false; } QSqlQuery stock(db); stock.prepare(UPDATE goods SET stock stock - ? WHERE id ? AND stock ?); stock.addBindValue(item.count); stock.addBindValue(item.goodsId); stock.addBindValue(item.count); if (!stock.exec() || stock.numRowsAffected() ! 1) { db.rollback(); errMsg 库存不足 item.name; return false; } } if (!db.commit()) { db.rollback(); errMsg 提交失败; return false; } return true; }transaction、commit、rollback三条指令缺一不可。很多源码只在最后commit中间失败就脏数据rollback要覆盖每条失败路径。UPDATE goods SET stock stock - ? WHERE id ? AND stock ?是防超卖的关键把“库存够不够”的判断压进SQL受影响行数为0说明锁库存失败立即回滚。这比先SELECT再UPDATE的写法更稳并发场景下也能挡住超卖。lastInsertId拿自增订单号SQLite在Qt下可用但注意必须在同一事务连接上执行。循环里逐条new QSqlQuery是简单写法性能没问题订单明细几百行以上再改成一次prepare循环bind。另一个常见坑是在同一个事务里混用两个数据库连接。如果createOrder用了成员m_db但中间某段又调用了QSqlDatabase::database()默认连接SQLite会当成第二个连接事务隔离导致rollback不起作用。我一般统一用QSqlDatabase::database()取当前连接避免成员变量和默认连接不统一。4.4 QSS界面设计三行样式告别“作业感”界面丑不丑对答辩印象分影响很大但没必要去重写QPainter。QSS是校园商铺系统界面设计里投入产出比最高的一环QPushButton { background-color: #2d8cf0; color: white; border-radius: 4px; padding: 6px 16px; } QPushButton:hover { background-color: #57a3f3; } QTableView { gridline-color: #e8eaec; selection-background-color: #d9ecff; }把这段setStyleSheet到MainWindow按钮从默认灰块变成圆角蓝色表格线变浅选中行变浅蓝整个界面就从“作业感”变成“有点设计”。字体大小和间距别在QSS里调太多窗口缩放适配容易乱。想再进一步给登录窗口加一张背景图用QLabel加setPixmap即可资源走qrc路径别用磁盘绝对路径。5. Qt校园商铺系统高频踩坑五条能照着改的排错记录环境对了、业务读懂了后面真正的消耗在排错。我把课设里出现频率最高的几类问题和修复手法列在这里每条按“现象→原因→解决”写。这些不是玄学都是能稳定复现的工程问题。5.1 中文乱码源码、数据库、字体三层各管各的现象有两种界面按钮文字变成Îļþ这类拉丁乱码商品名称从SQLite读出来变成问号。原因也在两层源码文件被编辑器以GBK保存Qt5默认按UTF-8解释源码字符串数据库字段存的是UTF-8但没在任何层面声明。解决方法是统一三层编码源码文件全部以UTF-8保存Qt Creator右下角可切换字符串常量用QStringLiteral包裹建库时执行PRAGMA encoding UTF-8;读出来的字节用QString::fromUtf8兜底。Qt6默认源码UTF-8这类问题少大半。字体层单独看Windows下用微软雅黑Linux用Noto Sans CJK否则中文会显示成方块。排查时先分清是源码层还是数据库层打印一个常量字符串看是否正常再看数据库读出来的值。5.2 编译报错 dependent ..\qt\5.15.2\msvc2019_64\include\qtwidgetsKit和编译器不匹配现象Kit选了Qt 5.15.2 MSVC2019 64-bit一点构建编译输出直接抛dependent错误指向msvc2019_64\include\qtwidgets。根源不是Qt包坏了而是编译器环境缺位MSVC Kit依赖Visual Studio的C工具链。机器上没装对应的Microsoft Visual C Build Tools组件时Qt头文件依赖的系统头文件链是断的。解决二选一装Visual Studio Installer里的“使用C的桌面开发”工作负载它会同时装好MSVC和Windows SDK或者干脆切到MinGW Kit。最常见的浪费是两个Kit来回切换卡在同一个报错上两小时最后发现只是Windows SDK版本太旧。更新完VS或WinSDK后回到Qt Creator的Kits里点一次“重新检测”再编译。5.3 QTableView刷新数据后行数越叠越多或只显示几十行现象做了搜索或切换用户后表里旧行还在新行叠在下面反过来有时数据有几百条视图只显示几十行。原因主要在model没有清干净。QStandardItemModel的clear()会清掉所有行和列但也会清掉表头所以必须先clear再重新setHorizontalHeaderLabels只setItem不清空行数会累积。视图显示行数不对另一个入口是setRowCount和填充数据的时序行数没更新时视图不认为模型发生了变化。解决刷新函数固定三段式——clear、设置表头、循环setItem最后setRowCount收尾。数据量变大时把整段刷新包在view-setUpdatesEnabled(false)和true之间可以减少闪烁。如果拿到手的是QAbstractTableModel重点看rowCount()是否返回了真实的行总数以及data()对空索引的处理。5.4 一按按钮就崩溃信号槽悬空指针和签名不匹配现象界面正常打开点某个按钮直接退出连报错框都没有。这类崩溃常见根因有两类。第一类connect到栈上临时变量槽里new的QDialog没有保存成成员对话框关闭后变成悬空指针下次信号来了命中野指针。第二类信号重载后connect的槽函数签名不匹配Qt5会静默丢弃这条连接表现成按钮点了没反应比崩溃还难查。解决新式指针语法connect带参数的重载显式指定函数指针跨窗口对象用成员变量持有构造时初始化并置空在可能为空的入口加Q_ASSERTQ_ASSERT(m_shopWidget ! nullptr); connect(m_shopWidget, ShopWidget::goodsClicked, this, MainWindow::onGoodsClicked);Q_ASSERT只在debug构建生效能最快暴露空指针。release版再用if判空替代。调试时看Qt Creator的“应用程序输出”面板出现ASSERT失败或segmentation fault字样后顺着调用堆栈往上翻最后一条你写的代码往往就是问题点。5.5 图片和图标不显示qrc资源路径大小写敏感现象QLabel::setPixmap加载图片运行出来空白。原因路径写成qrc:/images/a.png或绝对路径。Qt资源系统的正确前缀是:/加qrc是不少老源码里的写法当前版本直接失效。还有一点易忽略资源路径大小写敏感文件是Logo.png代码里写logo.png同样空白。解决先在qrc编辑器里确认alias前缀再复制Qt Creator状态栏提示的完整资源路径。如果确实要加载磁盘上的文件先QFile::exists判断再加QDir::currentPath()打印工作目录——绝对路径和相对路径在Qt Creator和双击exe时的工作目录不一样这也是图片不显示的常见非代码原因。6. 别急着加功能先学会用断点和qDebug验证一单生意想验证事务到底有没有生效我一般不在界面里反复点鼠标而是在createOrder里下两个断点第一个断点在db.transaction()成功之后观察items里的数量第二个断点在db.commit()之前检查numRowsAffected()。然后切到数据库执行SELECT stock FROM goods前后一对比就知道扣减对不对。Qt Creator的变量窗口能展开每个QVector元素比qDebug打印直观得多。给系统加“库存不足”拒绝下单的最小改动其实就是4.3代码里那行UPDATE的WHERE stock ?再检查受影响行数。很多人拿到源码会先加一段SELECT判断库存那样需要先查一次再更新两步之间仍有并发窗口把判断压进单条UPDATE里更稳。改完后用断点验证一遍把某件商品加购数量改成999看函数返回值和界面提示。有一个习惯我希望能帮到你拿到源码后第一件事是复制一份原始压缩包存着再开始改。我在早期课设里经常删掉原作者的一整段“丑陋代码”后重写结果自己的实现也有bug想回到原版却没有存档只能靠回忆二次重写后悔得不行。Git或zip备份是这套流程里最便宜的后悔药。希望这段从结构、编译、核心代码到踩坑的顺序能帮你在跑完这个QtC校园商铺系统后交出一份自己看得懂、敢答辩的成果。本文还有配套的精品资源点击获取
返回列表