68个Qt实战Demo:新手快速上手与老手查漏补缺的最小可运行现场

发布时间:2026/10/14 12:43:43

68个Qt实战Demo:新手快速上手与老手查漏补缺的最小可运行现场 简介这是一套面向C开发者与Qt初学者的系统性学习资源涵盖GUI开发、信号槽机制、多线程、数据库集成、网络编程、QML界面设计等核心模块帮助用户从零掌握跨平台桌面应用开发能力。压缩包共2000个文件主体为1210个cpp源码、813个h头文件、174个ui界面描述及244个pro工程配置文件辅以大量png图标资源与html文档说明结构完整、开箱即用整体大小153.44MB适配Windows/Linux/macOS多平台编译环境。目前已有471人下载学习每个Demo均独立可运行覆盖QWidgets控件组合、QCustomPlot图表绘制、MFCCharts兼容方案、线性代数算法实现等典型场景代码规范、注释清晰并包含moc生成文件与资源编译脚本便于理解Qt元对象系统与构建流程。1. 68个Qt学习Demo不是“超值”噱头而是新手绕不开的「最小可运行现场」你刚装好Qt Creator新建一个Widget项目点下运行——窗口弹出来了但里面空空如也。你翻文档QLabel怎么居中QVBoxLayout加了却没反应信号连了但槽函数死活不触发这不是你手慢是Qt的交互逻辑和UI构建范式必须靠亲手改、亲手删、亲手断点才能长进肌肉记忆。这68个Demo不是打包下载就完事的“资源合集”而是68个有明确目标、可独立编译、带注释、带常见变体的最小闭环场景从“让按钮点击后改变文字颜色”到“用QThread安全更新进度条”从“拖拽文件到窗口自动解析路径”到“QTableView绑定自定义模型并支持右键菜单”。它不教C基础不讲MVC理论只解决你写第3个界面时卡住的那5分钟——比如为什么setStyleSheet在show()之后才生效为什么QFileDialog::getOpenFileName返回空字符串却没报错。适合两类人刚过完《C Primer》第7章、想立刻做出能动的东西的新人以及用Qt写了两年、但每次新加一个QGraphicsView都要重查文档的老手。它不是替代文档而是把文档里分散在12个章节里的碎片操作压进一个.pro一个.cpp一个.h的三件套里。2. 用Qt Creator本地跑通第一个Demo从解压到断点单步执行的完整链路2.1 解压与项目结构识别别急着双击.pro文件拿到压缩包后不要直接双击.pro文件打开——这是新手最常翻车的第一步。Qt Creator对项目路径中的中文、空格、特殊符号极其敏感而压缩包解压后默认可能落在“下载”或“桌面”这类路径里。正确做法是# 在终端Linux/macOS或 PowerShellWindows中执行 mkdir -p ~/qt-demos/first-demo unzip qt-demos-68.zip -d ~/qt-demos/ # 确认解压后存在类似这样的目录 # ~/qt-demos/demo_01_button_color_change/ # ├── button_color_change.pro # ├── main.cpp # ├── widget.h # └── widget.cpp提示demo_01_button_color_change这类命名不是随意的数字前缀代表难度递进_分隔符后的词组直指核心功能。68个Demo中前12个全部围绕QWidget基础控件交互是必须优先打通的“地基层”。2.2 Qt Creator配置选对Kit比写代码还关键打开Qt Creator → “Open Project” → 选择button_color_change.pro→ 弹出Kit选择界面。这里必须手动确认三点检查项正确值示例错误表现后果CompilerMinGW 11.2 (64-bit)或MSVC 2019 x64显示为None或Auto-detected编译失败报错qmake is not recognizedQt versionQt 6.5.3 (MinGW 11.2 64-bit)显示为Qt 5.15.2且项目含QMetaObject::connectSlotsByName调用运行时报QObject::connect: No such slotCMake generator留空因是qmake项目勾选了Ninja或MinGW Makefiles构建过程卡在Running CMake...无限转圈确认后点击“Configure Project”。此时Qt Creator会在项目根目录生成build-button_color_change-Desktop_Qt_6_5_3_MinGW_64_bit-Debug/这样的构建目录——这个路径不能含中文、空格、括号否则后续qmake会静默失败。2.3 运行前必做的三处代码验证打开widget.cpp找到构造函数内关键段落// widget.cpp 第23行起典型写法 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); // ← 必须存在且在所有ui成员访问之前 connect(ui-pushButton, QPushButton::clicked, this, Widget::onButtonClicked); // ← 信号连接必须在setupUi之后 ui-label-setStyleSheet(color: blue;); // ← 样式设置必须在show()之前错见避坑章 }检查重点ui-setupUi(this)是否在构造函数最开头若被移到connect之后ui-pushButton将为nullptr程序启动即崩溃connect的第四个参数是否为Widget::onButtonClicked取地址符不能漏漏掉则连接无效点击无响应ui-label-setStyleSheet(...)是否在show()调用前这是玄学高发区——实际需在show()之后或resizeEvent中设置才可靠原因见第4章避坑。完成检查后按CtrlRWindows/Linux或CmdRmacOS运行。窗口弹出点击按钮文字颜色应实时变为蓝色。若未变色立即打开“Application Output”面板看是否有QObject::connect: No such slot类报错——这是信号槽未正确绑定的铁证。3. 68个Demo的模块化拆解按技术纵深分层拒绝“全量导入”3.1 地基层Demo 01–12QWidget控件的“手感训练”这一层不涉及模型、线程、网络只做一件事让每个基础控件“活”起来。例如demo_07_slider_with_label目标是拖动QSlider时同步更新QLabel显示当前值。其核心不在算法而在理解Qt事件流// demo_07_slider_with_label/widget.cpp void Widget::onSliderValueChanged(int value) { // 注意此处value是原始int非百分比 ui-label-setText(QString(当前值%1).arg(value)); // 关键QSlider默认范围是0–99若需0–100需调用setRange(0,100) }常见误用开发者直接在onSliderValueChanged里调用ui-slider-setValue(value 1)试图实现“拖动时自动1”结果滑块疯狂抖动。原因setValue()会再次触发valueChanged信号形成无限递归。正确解法是加标志位或用blockSignals(true)临时屏蔽——这个细节在Demo 07的注释里已标红。3.2 交互层Demo 13–32事件、绘图与自定义Widget的临界点当QLabel和QPushButton不再够用就需要接管绘制和事件。demo_22_custom_paint_widget是典型继承QWidget重写paintEvent()用QPainter画渐变圆角矩形。关键代码段// demo_22_custom_paint_widget/customwidget.cpp void CustomWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿必须显式开启 QLinearGradient gradient(0, 0, width(), height()); gradient.setColorAt(0, Qt::blue); gradient.setColorAt(1, Qt::cyan); painter.setBrush(gradient); painter.setPen(Qt::NoPen); // 若不设NoPen边框会覆盖渐变填充 painter.drawRoundedRect(rect(), 12, 12); // 圆角半径不能超过宽高一半否则渲染异常 }参数说明setRenderHint(QPainter::Antialiasing, true)不加此句所有曲线/圆角均为锯齿状视觉上像“毛边”drawRoundedRect(rect(), 12, 12)第二个、第三个参数是xRadius和yRadius若设为width()/2在窗口缩放时可能超出边界导致崩溃setPen(Qt::NoPen)若保留默认黑色边框会盖住渐变色初学者常以为“渐变没生效”。3.3 架构层Demo 33–68Model/View、多线程与跨平台适配的实战切口这一层开始出现真实项目级问题。demo_45_thread_safe_progress解决的是经典痛点后台计算时更新UI进度条。它不用QThread::msleep()阻塞主线程而是用QThreadPoolQRunnable// demo_45_thread_safe_progress/worker.cpp class ProgressWorker : public QObject { Q_OBJECT public: explicit ProgressWorker(QObject *parent nullptr) : QObject(parent) {} signals: void progressUpdated(int value); void finished(); public slots: void doWork() { for (int i 0; i 100; i) { QThread::msleep(50); // 模拟耗时任务 emit progressUpdated(i); // 信号跨线程安全Qt自动排队 } emit finished(); } };关键设计ProgressWorker继承QObject而非QThread避免手动管理线程生命周期doWork()作为槽函数在QThreadPool中执行信号progressUpdated由主线程的QEventLoop接收天然线程安全UI层只需connect(worker, ProgressWorker::progressUpdated, ui-progressBar, QProgressBar::setValue)无需moveToThread()等黑匣子操作。注意Demo 45的.pro文件中必须包含QT concurrent否则编译报QThreadPool: No such file——这是68个Demo中唯一强制依赖concurrent模块的案例。4. 避坑68个Demo里高频踩中的5个“静默失败”点4.1 现象QFileDialog::getOpenFileName返回空字符串控制台无报错原因调用时传入的parent参数为nullptr且当前平台尤其是macOS的文件对话框策略要求有效父窗口。Qt静默失败不抛异常也不打印日志。解决确保getOpenFileName第一个参数为this即当前Widget指针而非nullptr。若在非Widget类中调用需通过QApplication::activeWindow()获取顶层窗口。4.2 现象QTimer::singleShot(0, this, MyClass::onTimeout)的槽函数从未执行原因this对象在singleShot调用后立即被析构如在QDialog::accept()后delete this导致Qt无法投递事件。解决改用QTimer::singleShot(0, this, MyClass::onTimeout)前先调用this-setAttribute(Qt::WA_DeleteOnClose, false)或改用QMetaObject::invokeMethod(this, MyClass::onTimeout, Qt::QueuedConnection)后者在对象销毁时自动丢弃待处理事件。4.3 现象QTableView设置了QStandardItemModel但表格空白无数据原因QStandardItemModel::setItem(row, col, item)中item为栈对象如QStandardItem item(text)离开作用域即析构模型内部指针悬空。解决必须用new QStandardItem(text)创建堆对象或使用model-setData(model-index(row, col), text, Qt::DisplayRole)——后者更安全无需手动内存管理。4.4 现象QPainter::drawText()文字位置偏移尤其在HiDPI屏幕如MacBook Pro上严重原因drawText(x, y, text)的y是基线baseline位置非顶部。HiDPI下字体度量变化y需动态计算。解决改用QPainter::drawText(rect, Qt::AlignCenter, text)或用QFontMetrics fm(font()); int y rect.top() fm.ascent() 2;精确计算基线。4.5 现象QProcess启动外部程序成功但readyReadStandardOutput信号不触发原因子进程输出缓冲区未刷新如Python脚本未调用sys.stdout.flush()或Qt未设置QProcess::setProcessChannelMode(QProcess::MergedChannels)合并stdout/stderr。解决在子进程中强制刷新Python加print(..., flushTrue)并在Qt端调用process-setProcessChannelMode(QProcess::MergedChannels)再连接readyReadStandardOutput。5. 进阶技巧用68个Demo反向构建你的“Qt能力图谱”5.1 以Demo为锚点建立可检索的本地知识库68个Demo的价值不仅在于运行更在于成为你提问的“上下文”。我习惯在每个Demo目录下新增NOTES.md记录三个问题这个Demo解决了什么具体场景例demo_38_drag_drop_files→ “用户拖拽多个.log文件到窗口自动读取首行时间戳并显示在QListWidget”如果需求微调改哪几行例若需支持拖拽文件夹只需在dropEvent()中增加QDir(dirPath).entryInfoList(QDir::Files)遍历它暴露了Qt哪个底层机制例demo_38揭示QMimeData如何序列化文件路径QUrl::toLocalFile()为何在macOS需额外QUrl::toString(QUrl::FullyEncoded)处理空格这样当你下次遇到“需要从邮件附件提取图片”时大脑会立刻跳转到demo_38的QMimeData处理逻辑而非重新搜索“Qt email attachment”。5.2 将Demo转化为自动化测试用例守住重构底线68个Demo中有19个具备明确输入输出如demo_15_calculator输入数字和运算符输出计算结果。我用QTest为它们补全单元测试// test_demo15.cpp void TestCalculator::testAddition() { Calculator calc; QCOMPARE(calc.calculate(23), 5); // 输入字符串输出int QCOMPARE(calc.calculate(10-7), 3); }关键动作在demo_15_calculator目录下新建test/子目录创建test_demo15.cpp继承QTest.pro文件追加QT testlib和SOURCES test/test_demo15.cpp运行./build-demo15-test-Desktop_Qt_6_5_3_MinGW_64_bit-Debug/test_demo15即可验证。此举让Demo从“一次运行”变成“持续可验证资产”。当我把Calculator重构为支持浮点数时testAddition()失败会立刻提醒我漏改了calculate()的返回类型。5.3 用Git Submodule管理Demo演进避免“改坏一个全盘回滚”68个Demo并非静态快照。某次我为demo_52_network_request添加HTTPS证书校验结果导致demo_41_serial_port的串口枚举失效因全局SSL配置污染。血泪经验永远不要在主项目中直接修改Demo源码。正确做法是# 在自己项目根目录执行 git submodule add -b main https://github.com/xxx/qt-demos.git vendor/qt-demos git submodule update --init --recursive然后在自己项目的.pro中引用include(vendor/qt-demos/demo_01_button_color_change/button_color_change.pri) # pri文件导出HEADERS/SOURCES避免重复include这样vendor/qt-demos保持只读所有定制化修改都在自己项目层完成。升级Demo只需cd vendor/qt-demos git pull冲突仅发生在你主动修改的pri文件里而非68个原始cpp/h。最后说一句实在话我最初也觉得“68个Demo”是营销话术直到我把demo_29_qgraphicsview_zoom的缩放逻辑抄进自己的图像标注工具省掉两天调试时间——那一刻才懂所谓“超值”就是当你在凌晨两点对着QGraphicsView::scale()文档抓狂时能立刻打开一个已验证的、带注释的、可运行的参照物。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/14 12:43:43

C# 打印条码标签实战:ZXing.Net 与 PrintDocument 避坑指南

简介:这是一份面向C#开发者、聚焦条码标签打印场景的实战Demo,适合从事物流、仓储、零售等桌面应用开发的中级学习者参考。项目围绕条码生成与打印展开,涉及第三方条码库与ZPL/EPL指令调用、GDI图形绘制、PDF与图像文档格式化、串口及网络打印…

2026/10/14 12:43:43

YARN调度器深度解析:Fair与Capacity选型、参数调优与故障排查

1. 项目概述:为什么一个调度器值得单独写三篇?Yarn调度器——这个词在日常开发中出现频率其实不高,但凡你遇到过“任务卡在ACCEPTED状态不动”“明明集群资源充足却一直排队”“同一个队列里A任务占满资源,B任务饿死”这类问题&am…

2026/10/14 14:14:56

王澍建筑理念:传统与现代的对话与创新

1. 王澍建筑理念的独特魅力"看到这一句狂语被王澍圈粉了"这个标题背后,反映的是中国当代建筑界一个极具争议又充满魅力的现象。作为普利兹克建筑奖得主,王澍的建筑理念和言论常常打破常规,这种"狂语"恰恰体现了他对建筑本…

2026/10/14 14:14:56

从小白到专家:掌握这三类核心能力,进军AI医疗大模型领域

文章详细阐述了在医学领域成功应用AI技术所需具备的三类核心能力:1)医学专业能力,包括临床需求转化、医疗合规伦理、医学知识图谱构建;2)AI技术理解力,涵盖算法逻辑拆解、数据闭环管理、大模型应用&#xf…

2026/10/14 14:14:56

基于PLC的物料分拣系统:设计、选型与调试实践

做物料分拣这套系统,我最早是被一条真实的生产线“逼”出来的。当时现场有一道工序需要把三种不同属性的工件从同一条传送带上分离开,原先靠两个工人站在线边手动挑拣,一天干下来眼睛酸不说,漏检率一高,后道装配就得跟…

2026/10/14 14:14:56

想入行AI大模型开发?小白程序员看这篇,手把手教你拿Offer

本文为AI应用开发新手提供了一份实用指南,强调无需精通底层模型,先从Python基础、RAG、Function Calling等应用层技能入手。文章建议通过LangChain、LlamaIndex等框架及千帆、ModelScope等平台实践,并利用GitHub开源项目积累经验。同时强调业…

2026/10/14 14:09:56

基于YOLOv5与视觉伺服的机械臂eye-in-hand抓取:从检测到MoveIt控制

简介:这份资源面向机器人视觉伺服方向的开发者与学习者,提供一套基于YOLOv5目标识别、MoveIt动作规划与Gazebo仿真的eye-in-hand视觉伺服完整工程。它解决的是相机与机械臂协同定位、目标识别后自动生成抓取动作的集成问题,适合具备ROS基础、…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/13 17:09:18

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/14 2:32:55

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/14 0:00:33

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:33

macOS/iOS高精度计时:mach_absolute_time原理与实战

1. 项目概述:为什么mach_absolute_time是 macOS/iOS 时间测量的“黄金标准”在 macOS 和 iOS 开发中,我见过太多人用CFAbsoluteTimeGetCurrent()或NSDate.timeIntervalSinceReferenceDate做性能打点,结果在高精度场景下被系统时钟跳变、NTP 同…

2026/10/14 0:00:33

SCORM课件演示与测试全解析:从API通信到自动化验证

简介:这是一套遵循SCORM标准的交互式课件演示与测试资源,面向E-Learning课程开发者、LMS平台测试人员及在线教学从业者,用于验证课件在不同学习管理系统中的识别、传递与跟踪能力。压缩包共28个文件,约12.07MB,以swf动…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑