尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

用Qt打造个人日程管理工具:从需求到打包发布的完整实践

发布时间:2026/9/9 17:58:43

资讯中心
01
ARTICLE

用Qt打造个人日程管理工具:从需求到打包发布的完整实践

用Qt打造个人日程管理工具:从需求到打包发布的完整实践
简介这是一套基于Qt开发的个人日程安排处理项目源码面向具备C基础、希望掌握Qt桌面应用开发的读者演示了日程创建、分类管理、日期筛选、定时提醒等完整事务流程。项目综合运用QCalendarWidget日历组件、QDateTimeEdit时间编辑、QTableView模型视图、QTimer定时器以及SQLite数据持久化等Qt核心技术能够帮助学习者理解GUI与业务逻辑分离的工程思想。资源共89个文件包含15个cpp和15个h源文件、6个ui界面设计文件、11个dat日程数据文件、pro/sln工程配置文件以及编译好的exe可执行程序压缩包整体仅10.83MB结构完整便于按模块研读。目前已有468人学习参考。借助这套源码可以快速搭建一个功能可用的个人日程工具并对照实际代码掌握界面布局、信号槽联动、数据读写和提醒触发的实现细节非常适合作为Qt课程设计、毕业设计或入门实战的参考范本。 最近在折腾个人时间管理索性用 Qt 自己写了一个“个人日程安排处理事务”的小工具。起因很实在市面上日程软件功能越来越重数据还要同步到云端我就想在本地快速记几件事、到点弹个提醒、按周看看自己的时间花在哪顺手还能把 Qt 这些年攒的经验用上。Qt 做这类桌面工具确实顺手C 原生性能、Widgets 组件成熟、跨平台编译方便后期想加网络同步、串口联动也不缺库。这篇文章把整个实现过程、环境搭建、打包发布的细节包括踩过的坑都完整记录下来给正准备用 Qt 做类似小工具的朋友当个参考。1. 先想清楚做什么个人日程工具的需求边界1.1 核心需求与功能拆分个人日程安排处理事务听起来范围很大但真正常用的功能其实就三块日程录入与编辑、到点提醒、按时间维度查看。我在动手前先把需求按“必须做、可以做、先不做”分类避免一上来就把项目做膨胀。必须做的有日程的增删改查、日期时间选择、一次性/重复日程区分、到点弹窗提醒、本地数据保存。可以但有难度的有周视图时间轴图形化、托盘常驻、QSS 美化界面。先不做的有多人协作、日历订阅、跨设备云同步、语音助手这类偏重的功能。这个分类很重要。很多人写个人工具失败不是因为代码写不好而是需求清单失控。一个最小可用版本应该在一周内能写出核心闭环而不是花一个月把所有想法都塞进第一版。1.2 技术选型为什么是 Qt Widgets 而不是其他方案在选型上我也犹豫过。Electron 虽然界面好写但启动速度和内存占用对一个小工具来说太奢侈C# WPF 只在 Windows 上舒服换到 Linux 又得重来Qt Widgets 与 QML 之间我最终选了 Widgets原因是它写传统表单类界面最直接日历控件、日期时间选择器都有现成封装路由和状态管理也不需要像 QML 那样额外维护一套。Qt 5.15.2 是这次的主力版本。原因很现实Qt 6 对第三方组件的兼容还在过渡期而 5.15.2 属于 LTS 分支QCustomPlot 这类常用绘图库的适配非常成熟网上资料多遇到问题能搜到解决方案。编译器方面我用 MinGW 64-bit 做日常开发发布时再切换到 MSVC 版本做兼容性验证。2. Qt 版本选择与环境搭建的实操记录2.1 版本与编译器组合怎么定如果你也打算做桌面小工具我的建议是 5.15.2 配 MinGW 起步。MinGW 工具链的好处是开源、免配置、Qt 官方在线安装包自带不需要额外装 Visual Studio。等你要发布给其他 Windows 用户或者要接某些只提供 MSVC 版 SDK 的第三方库时再装一套 MSVC 2019 编译器也不迟。另一个常被忽略的问题是编译器位数。现在绝大多数 Windows 是 64 位系统但某些老库只有 32 位版本。做个人工具建议统一用 64 位省得后续接库时遇到 ABI 不匹配的尴尬。顺带说一句Qt 5.12.12 也是个稳妥选择如果你的目标机器上有老系统兼容性要求可以两个版本都装上用 Qt Creator 的 Kit 切换即可。2.2 国内镜像下载与安装组件选择Qt 官方下载页面访问速度不稳定我通常走清华镜像地址格式是 https://mirrors.tuna.tsinghua.edu.cn/qt/online_installers/ 下的在线安装器或者直接下载 archive 里的离线包。离线包的好处是安装速度快、失败率低推荐下载 qt-opensource-windows-x86-64-5.15.2.exe 这类完整安装包。安装时组件按需勾选不要全选。我这次只勾了 Qt 5.15.2 下的 MinGW 8.1.0 64-bit、Qt Debugger 和 Qt Creator外加 Sources 源码包总占用大概 3GB 左右。源码包建议勾上调试时按 F2 跳进 Qt 源码看实现非常有用没有源码你连项目符号都看不了。安装完成后在 Qt Creator 里确认套件注意看“Qt version”和“Compiler”是否都识别成功。经常有人卡在这里编译器路径没配好或者 qmake 版本号还是一串红色警告后面编译必出问题。3. 工程搭建与界面布局设计3.1 新建工程与 UI 方式的选择Qt Creator 里新建 Qt Widgets Application类名 MainWindow基类选 QMainWindow。UI 方面我这次是 Qt Designer 拖控件和手写布局混着来简单的按钮、列表用 Designer 拖动态更新的区域手写代码。说实话像日程管理这种中小型界面直接手写布局反而更清晰。Designer 生成的 ui_mainwindow.h 每次编译都重新生成你要动态增删组件时还得回到 .ui 文件里去改。不过 Designer 在摆静态控件时确实快两种方式配合效率最高。如果你用 VS Code 配 Qt Designer也是同样思路.ui 文件最后还是要通过 uic 转成头文件编进项目。3.2 主界面布局与信号槽连接主界面我做了左右分栏左边是 QCalendarWidget 日历控件右边是 QListWidget 日程列表下面一排按钮负责新增、编辑、删除。分栏用 QSplitter 包起来用户能拖动比例体验比固定布局好很多。QSplitter *splitter new QSplitter(this); splitter-addWidget(calendarWidget); splitter-addWidget(listWidget); splitter-setStretchFactor(0, 1); splitter-setStretchFactor(1, 2); setCentralWidget(splitter);这里最容易忽略的是日历选择日期变化时要刷新列表信号槽连接写不完整就会出现翻日历没反应、点按钮没弹窗之类的“假死”现象。我习惯把刷新动作抽成一个 refreshList() 函数日历选中日期、增删改完成、窗口重新显示时统一调用这样逻辑只维护一处。4. 核心功能实现数据、提醒与持久化4.1 日程数据结构与 JSON 存取日程数据我用结构体保存在内存里字段包括 id、标题、开始时间、是否重复、是否已提醒。因为个人工具数据量很小不引入数据库直接用 JSON 文件持久化。JSON 的好处是纯文本、可读、改起来方便用 QJsonDocument 读写也就几行代码。struct Schedule { int id; QString title; QDateTime startTime; int repeatType; // 0: 不重复, 1: 每天, 2: 每周 bool reminded; };保存和加载的核心逻辑很简单但要留意 QDateTime 转字符串时用 Qt::ISODate 格式否则时间解析容易出时区偏差。中文环境下的日期格式最好也统一用 ISO 格式存入文件界面展示时再通过 QLocale::toString 转成“2025-01-16 09:30”这种显示格式避免乱码。QJsonArray arr; for (const auto s : scheduleList) { QJsonObject obj; obj.insert(id, s.id); obj.insert(title, s.title); obj.insert(startTime, s.startTime.toString(Qt::ISODate)); obj.insert(repeatType, s.repeatType); obj.insert(reminded, s.reminded); arr.append(obj); } QFile file(schedule.json); if (file.open(QIODevice::WriteOnly)) file.write(QJsonDocument(arr).toJson(QJsonDocument::Indented));4.2 重复日程的处理逻辑重复日程是这次开发里最容易绕晕的地方。“每天重复”“每周重复”听起来简单但对“到点是否提醒”影响很大。我的处理方式是新增日程时选了重复类型则只存一条基础日程判断提醒时用日期差值取模来判断今天是否属于重复日。比如一个“每周一晨会”的日程startTime 存的是下周一 09:00repeatType 为 2。检查时先算出今天相对 startTime 过了几天如果对 7 取模等于 0就认为是重复触发的日子再把提醒时间临时算到今天的 09:00。这个逻辑还要处理“上周期已提醒过”的状态所以我专门加了一个 remindedDate 字段记录最后一次提醒的日期避免同一个日程当天被提醒好几次。4.3 提醒机制与托盘常驻提醒我用的方案是 QTimer 定时轮询每 30 秒检查一次当前时间判断有没有日程落在提醒窗口内。Qtimer 不精确但对分钟级提醒完全够用。真到秒级任务那就得上多线程定时器了个人日程场景没必要。QTimer *timer new QTimer(this); connect(timer, QTimer::timeout, this, MainWindow::checkRemind); timer-start(30000); void MainWindow::checkRemind() { QDateTime now QDateTime::currentDateTime(); for (auto s : scheduleList) { if (!s.reminded s.startTime now s.startTime.addSecs(15 * 60) now) { s.reminded true; QMessageBox::information(this, 日程提醒, s.title \n s.startTime.toString(yyyy-MM-dd hh:mm)); } } }另外我加了 QSystemTrayIcon 托盘图标关闭主窗口时最小化到托盘而不是退出程序。这里有个小坑托盘菜单的“退出”按钮要记得调用 qApp-quit()而不是直接 close() 主窗口否则任务管理器里进程还在点击托盘图标又拉不起窗口。5. 日程可视化的图形实现5.1 为什么引入 QCustomPlot文字列表虽然清楚但一周的日程有没有分布不均、哪天最忙光看列表很难直观感知。我决定加一个“一周日程分布”视图按星期统计每天日程数量画成柱状图。绘图库选了 QCustomPlot它开源、轻量、qmake 直接加源码文件就能用不像 QChart 那样需要额外模块授权。QCustomPlot 其实不仅能画柱状图时域波形转频域曲线、实时数据流绘制都能做。我做日程管理时只用了它的基础图表能力但它的 QCPGraph、QCPBar、QCPFinancial 等接口都是同一套坐标系逻辑理解一个就通了大半。5.2 QCustomPlot 集成与柱状图实现集成 QCustomPlot 只需要两步把 qcustomplot.h 和 qcustomplot.cpp 放进工程然后在 .pro 文件里加上 printsupport 模块。版本我用的是 2.1.1官方源码包直接塞进项目相对路径不污染 Qt 安装目录团队协作也方便。QT core gui widgets printsupport INCLUDEPATH $$PWD/third_party/qcustomplot SOURCES $$PWD/third_party/qcustomplot/qcustomplot.cpp绘制柱状图时横轴是周一到周日纵轴是当天日程数量。QCPBars 接受两个 QVector一个放横坐标刻度一个放纵坐标数值代码非常简洁。QVectordouble days, counts; for (int d 1; d 7; d) { days.append(d); counts.append(countByWeekday(d)); } QCPBars *bars new QCPBars(customplot-xAxis, customplot-yAxis); bars-setData(days, counts); customplot-xAxis-setRange(0, 8); customplot-yAxis-setRange(0, maxCount 1); customplot-xAxis-setLabel(星期); customplot-yAxis-setLabel(日程数量); customplot-replot();5.3 展示密度之外的扩展思路柱状图只是入门后面我还想加一个按时间段展示的甘特图样式横轴是 24 小时纵轴是星期每个日程画成一个色块。实现方式可以直接用 QCPFinancial 的蜡烛图接口魔改也可以干脆重写 paintEvent 在 QWidget 上画矩形前者省事后者可控性更高。如果你做的是信号处理相关项目QCustomPlot 画完时域波形后还能接 kissfft 这类 FFT 库把波形转换到频域再画曲线原理都是把数据 setData 到 QCPGraph 上只是数据来源从时间轴换成频率轴。绘图组件本身不挑数据挑的是你给它的坐标系和数据维度。6. 打包发布与常见报错排查6.1 windeployqt 打包完整步骤个人工具最终要发给别人用打包发布这一步跑不掉。Qt 程序不能直接把 exe 拷走就完事运行时会依赖 Qt5Core.dll、Qt5Gui.dll 等一堆动态库还要求 plugins 目录里有对应平台插件。正确做法是先用 Release 模式编译然后在 Qt 命令行环境里执行cd /d 你的exe目录 windeployqt 日程安排.exewindeployqt 会自动扫描 exe 依赖的 Qt 模块把需要的 DLL、插件、翻译文件拷贝到同目录。执行完一定要检查 platforms 目录下有没有 qwindows.dll这个文件缺失或版本不对就是后面要说的那个经典报错。6.2 “no Qt platform plugin could be initialized” 排查“windows no qt platform plugin could be initialized” 这个报错我遇到过两次一次是忘了执行 windeployqt一次是从 5.15.2 的程序里手工拷 DLL 到另一个安装着 Qt 6 的机器上。原因都一样程序找不到 platforms/qwindows.dll或者找到的插件和 Qt 库版本不匹配。解决办法分三步确认 exe 同级目录存在 platforms/qwindows.dll确认 qwindows.dll 与 exe 使用同一个 Qt 版本和编译器位数编译最后用 Process Explorer 或 windeployqt 的 verbose 输出检查 DLL 搜索路径避免系统里另一个 Qt 目录干扰加载顺序。Debug 和 Release 的依赖库绝不混用这是最容易被忽略的坑。6.3 跨平台发布的补充如果你要把工具跑到 Linux 上记得 Linux 下没有 windeployqt 的完全等价物可以用 linuxdeployqt 打包 AppImage或者直接 qmake 加 make 编出可执行文件后写一个启动脚本设置 LD_LIBRARY_PATH 指向 Qt 安装目录的 lib 子目录。寻找 Qt 安装路径可以用qmake -query QT_INSTALL_PREFIX这个命令也会用在 CMake 脚本里自动拼接第三方库路径。麒麟这类国产 Linux 发行版装 Qt 也遵循同样逻辑离线安装包解压后手动指定 qmake 路径即可。7. 开发中的崩溃问题与调试技巧7.1 常见崩溃场景复盘开发两周崩溃集中在三个地方QListWidget 删除项后继续访问旧 item 指针、JSON 解析失败时 QJsonObject 取值直接崩、lambda 里捕获 this 后窗口被销毁。第一个是典型悬空指针解决办法是删除前先 disconnect 相关信号删除后立即置空指针。JSON 解析的问题也很有代表性很多崩溃不是代码逻辑错而是数据文件被人为改坏或者版本升级后字段名对不上。现在我的 load 函数开头就判断 QJsonDocument::fromJson 的 error 返回值并在界面打印错误位置排查速度提升了一大截。7.2 Qt Creator 与 VS Code 的调试取舍调试工具我主力用 Qt Creator断点、调用栈、局部变量查看都够用。有人喜欢 VS Code装上 Qt 插件也能配置 Qt Designer 和 qmake但 VS Code 的 CMake 配置对新手不太友好尤其当项目里混合了 .ui 文件和 qrc 资源时调试配置容易出错。2024 年的实际体验来看Qt Creator 在 Qt 项目上的开箱即用程度仍然明显领先。配置环境时还有个小技巧国内镜像源除了装包也可以配置 Qt 在线安装器的镜像加速。命令行里加上 --mirror 参数比如指向清华镜像的 qt 路径下载速度能快不少。7.3 共享 pri 文件与工程组织多个小工具共有一套公共代码时我把它抽成一个 common.pri在 .pro 里 include 进来统一维护编译选项和第三方库路径。举例来说几个项目都要用 QCustomPlot 和 QSerialPortpri 里就集中写QT serialport printsupport INCLUDEPATH $$PWD/../third_party SOURCES $$PWD/../third_party/qcustomplot/qcustomplot.cpp这样每个子项目的 .pro 文件就只剩应用本身的源文件列表干净也容易维护。8. 后续扩展方向与开发体会8.1 网络同步与外部设备联动日程数据如果能跨设备同步实用性会提高一截。Qt 里用 QNetworkAccessManager 发请求时要注意哪几个要点正好踩过一个坑POST 请求如果忘了设置 Content-Type 头服务端可能直接回 405 “Request method POST not supported”。另外 GET 和 POST 的用法差异很大个人数据提交用 POST不要把敏感信息挂到 URL 参数上。串口联动也可以玩一下比如日程到点后通过 QSerialPort 给外部设备发指令或者读取门禁、打卡数据自动生成日程事件。Qt 的串口模块在 Qt Serial Port 里配置波特率、数据位、停止位之后 open 就能收数据但要注意不同平台的串口名称规则不一样Windows 是 COM3Linux 是 /dev/ttyUSB0。8.2 第三方库调用与多语言支持如果要接 Halcon 做日程卡片 OCR 识别思路和接 QCustomPlot 类似把 halcon 的 include 和 lib 路径加进 .pro头文件 extern “C” 包好就能调用。Qt 程序多语言发布用 Qt Linguist 生成 .qm 文件再通过 QTranslator 在启动时加载界面文案就能动态切换。8.3 开发过程中的一点体会这次改造最大的收获并不是代码量增长了多少而是我意识到做个人工具要克制。每次想加新功能时先问自己这个功能是不是最小闭环必需的不是就先记在 TODO 里。我第一版塞了月视图、统计报表、主题换肤结果核心提醒功能反而拖到第二周才跑通。另外建议尽早把 QCustomPlot 这类绘制组件引入项目哪怕第一版只是简单画个柱状图因为它会反向推动你的数据结构设计。为了让图表展示方便我把日程数据从原来的散乱变量梳理成了统一的 QList 结构数据模型清晰之后列表、编辑器、提醒检查都跟着顺畅了。这个项目目前还在持续迭代下一步准备把周时间轴的色块图完成再把同步功能加上。如果你也在做类似的桌面工具这几个方案可以直接抄遇到具体问题欢迎一起聊。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。