尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
官方Calendar Widget示例拆解:从原理到工程实践掌握Qt日历控件
Qt安装包里藏着不少宝贝其中最容易被低估的就是官方自带的示例程序。今天想聊聊一个看着不起眼、实际上很耐琢磨的小例子Qt 5.14.2自带Examples里的Calendar Widget。很多刚开始接触Qt的朋友照着教程学会了QLabel、QPushButton、QLineEdit就觉得自己入门了。但真到要用日历、日期选择这类功能时往往会卡住——要么不知道有个现成的QCalendarWidget能用要么稀里糊涂拖了个控件进界面发现样式、交互、格式化一堆问题不知道怎么处理。这个示例刚好好就好在它用最传统的方式把一个日历控件应该具备的能力完整地展示了出来。没有花哨的架构没有繁琐的组件化封装就是老老实实地摆控件、连信号、处理逻辑。你把这个Demo跑起来玩明白再自己动手改造一遍就能摸清Qt桌面开发里数据绑定、界面刷新、信号槽通信这些基本功的门道。这篇就顺着我实际调试这个示例的路径把里面值得看的代码、值得踩的坑、值得扩展的思路全部梳理一遍给打算拿Qt做工具类软件、桌面管理应用或者想深入研究控件自绘的朋友做个参考。1. 先让示例跑起来环境准备与实际运行1.1 找到示例项目与打开方式Qt的Examples目录在安装时是跟着组件一起走的我用的5.14.2默认装在了安装盘的根目录下路径大约是Qt/Qt5.14.2/Examples/Qt-5.14.2/widgets/widgets/calendarlwidget。你如果装的时候没改过路径基本都能在这个结构里找到。需要注意区分widgets这个大分类下还有一个叫calendarwidget不带l的老版本例子你们要注意区分前者才是我们要看的那个带农历显示、多面板切换的Calendar Widget。打开项目文件很简单找到后缀为.pro的文件直接用Qt Creator打开就行。但如果你的电脑上同时装了多个版本的Qt比如老项目要5.9新项目要5.15这里就要特别小心——尽量把整个示例目录拷贝一份到你的工作目录里再打开避免直接在安装目录里改否则编译的时候不小心点错套件会在源码安装目录里留下一堆临时文件以后想卸载重装都麻烦。提示我的习惯是建一个专门放示例的文件夹比如D:/MyQtSamples把官方Examples里需要研究的项目整个复制过去再打开。这样做还有个额外好处官方目录是只读的倾向复制到自己地盘后想加调试输出、改代码都不受权限限制也不会污染原装文件。1.2 编译运行的全过程与常见环境坑这个示例用到的模块并不复杂核心就是widgets和gui所以编译成功率和环境关系非常大。我自己用5.14.2自带的MinGW 32位版本编译打开后直接点左下角的绿色三角按钮大概十几秒就能跑起来界面是一个比较简洁的日历窗口左侧是主日历网格右侧列了一排开发和演示用的控制选项。如果遇到编译报错最典型的场景是Kit选择不当。5.14.2安装时会让你勾选编译器常见的有MSVC 2017 64bit和MinGW 7.3.0 32bit两种。MinGW版对应的是QMake生成的Makefile编译时如果报找不到g多半是环境变量里没有加入MinGW的bin目录。这时候不要急着重装Qt打开Qt安装目录下的Tools/***/bin目录确认一下g.exe是否还在然后把路径加到系统Path环境变量重启Qt Creator基本就能解决。还有一类报错是找不到头文件比如提示QCalendarWidget: No such file or directory。这基本可以断定是pro文件里少了QT widgets这一行。这属于典型的工程配置问题不是环境坏了。检查.pro文件时我建议把guimodule也留着因为实例里用到了QIcon、QPalette这些界面相关的类没有gui模块加载的时候会报很多继承链上的符号错误。这个示例自己带的pro文件已经把模块写好了所以一般不会遇到但如果你们自己新建工程参考这段代码这个坑是逃不掉的。跑起来之后别急着写代码先花半小时把这个Demo的所有控件点一遍。它已经把QCalendarWidget的绝大多数API暴露成了右侧的可操作选项怎么用、怎么改属性直接界面点点点就能直观看到效果。这种“以Demo为说明书”的学习方式比翻一整本API文档高效得多。2. 拆开看看Calendar Widget的界面布局与交互逻辑2.1 界面构成与主要控件一打开Calendar Widget示例映入眼帘的左右分栏结构实际上就是Qt里很常见的QSplitter布局。左侧是一个常规的QCalendarWidget右侧是一个承载各类控制控件的QWidget容器。这种结构设计得很典型——左侧是业务展示区右侧是参数控制区任何想在运行时实时调整控件外观特性的Demo都几乎会用这么一套布局。看懂了它以后你做图像处理工具的参数调节面板、报表系统的筛选区时也能直接复用这套设计。在主日历上你能看到月份标题栏、周几表头、日期网格这三大部分。月份标题栏左侧右侧各有一个箭头按钮中间显示当前年月点一下箭头页面会整体翻到上个月或下个月。如果你再仔细点看中间那个年月文字会发现它不是死文本——整个区域本质是一个可交互的导航栏点击左右箭头或者切换到特定角度拖动时会联动刷新底部网格的日期分布。再看右侧的控制区从上到下挤着好几个控件一组单选框用来切换选择模式三个下拉列表分别控制水平表头格式、垂直表头格式和日期文本格式两个复选框控制是否显示格网和是否启用导航栏最底下还有一个文本编辑框用来输出当前选中日期的具体信息。理解每个控件的功能后你会发现它其实就是把QCalendarWidget的公开属性面板化——每改一个属性左侧日历立刻响应。这个“属性-控件”一一对应的设计强烈建议新手完整过一遍能极大缩短你对陌生控件从陌生到上手的时间。2.2 交互背后的数据链路这个示例最能体现Qt信号槽机制的地方就在于右侧那堆控制项和左侧日历之间的联动关系。拿“水平表头格式”这个下拉框来说它的选项有三个无表头、短格式比如显示“周一”、长格式比如显示“星期一”。这个下拉框在切换选项的时候触发的是currentIndexChanged信号而槽函数里调用的就是calendarWidget-setHorizontalHeaderFormat()。这里要注意下拉框选项的顺序必须和API枚举的索引一一对应——如果对应错了就会出现你选了短格式界面却变成无表头的奇怪现象。我调试时发现示例里还藏着一个比较隐蔽的数据同步逻辑当你在日历上点击选中某一天QCalendarWidget会发出selectionChanged信号右侧文本编辑框里显示的日期就会跟着变化。这个逻辑之所以值得单独拿出来说是因为它不是用connect连接的一个简单lambda表达式而是先连接了selectionChanged到某个更新函数上再由那个函数同时完成文本拼接和setPlainText。这种“一次信号多个动作”的处理方式非常符合日常开发中“修改数据后统一刷新界面”的需求。新手总喜欢在每个控件里直接调用UI的setText来更新界面但示例里这段代码反映出的思路是把界面刷新收敛到一个函数里数据变化走统一通道对后期维护极其友好。另外一个值得琢磨的交互细节是“最小日期”和“最大日期”两个控制项虽然在默认界面里有可能被放在第二页或者靠下的位置但它的存在其实是QCalendarWidget非常实用的功能之一。比如做预约系统时你希望用户只能在未来一个月内选日期就可以通过这两个接口限制可选范围如果设置最小日期晚于最大日期布尔型返回值会告诉你设置失败这在开发时也是很容易踩的边界问题。2.3 从示例里学到的控件布局经验这个示例的布局并不复杂但很多细节能做到“看起来清晰舒服”全靠两个点一是统一了控件之间的间距二是对按钮和下拉框使用了合理的最小宽度。我们在自己写代码时最怕的就是界面堆在一起按钮挤按钮。这里右侧面板的核心是使用了QVBoxLayout来做垂直排列再用QGroupBox对相关功能做了分组视觉上就能很自然地划分开功能区。QGroupBox带一个边框和标题栏老手喜欢用新手往往嫌它占地方。但这个场景下我不建议大家为了好看而删掉分组框因为它能在视觉上降低右侧参数面板的“扁平感”让用户一眼扫过去就能看出哪些控件管的是同一类事。如果你想要进一步调整间距可以在Qt Designer里双击示例界面或者直接看源代码里的addWidget和setSpacing数值。把间距从默认的6改成8到10左右观感会舒服很多。我是强烈建议大家在跑这个Demo时顺便把右侧那一列QGroupBox的宽度和内部控件的排列方式截图下来之后做任何工具软件时都能拿出来参考。3. 背后原理看懂QCalendarWidget的核心机制3.1 从日期计算到网格绘制QCalendarWidget看起来只是一个控件但去掉所有外观装饰后它的本质是一个按星期排布的日期网格。要理解这个网格怎么生成先要看懂它的内部运算逻辑。选定任意一个月份第一步是得到这个月第一天是星期几第二步要知道这个月一共有多少天然后按照从第0列到第6列对应周日到周六的位置把1号填进对应的格子接着逐天往后填充。这个逻辑听起来简单但真正实现时有两个关键点第一个是每周起始日的计算。QCalendarWidget内部会依赖一个日期时间库把“年月日”转换为“星期几”时底层算法涉及日历的推算规则尤其要考虑闰年、月份天数不同等因素。QCalendarWidget自己就封装了这套机制你不需要自己写模运算。第二个是跨月填充。当1号不是从第一列开始时1号前方的空白区域实际上是上个月的尾巴日期当本月最后一天没排满一周时末尾空白区域又放下个月的月初日期。很多自定义日历控件在做这块时都会做出两种风格一种是把空白区域留白另一种是把相邻月份的日期用灰色调显示出来。官方示例默认会把跨月日期正常显示但你可以通过自定义绘制函数paintCell去改变它的表现——如果你以后要做一个包含农历信息的日历控件就必须在这里动手脚。多提一句QCalendarWidget还有一个容易被忽略的刷新增量当它检测到年份或月份变化时会直接触发内部网格的重新计算。它内部维护了显示日期区间、当前选中日期、显示月份这三个状态。你在代码里调用setCurrentPage(int year, int month)它会立刻把网格内所有日期文字更新但如果只调用setSelectedDate而当前页和选中日期不在同一页时它不会自动翻页只会发信号。这个区别很多人容易搞混以为选中一个日期后日历就应该自动跳到那个月去。实际不会的你自己开发日历应用时要根据业务需求决定用户选的日期跨月份时需不需要setCurrentPage联动切换。3.2 日期文本格式与本地化Calendar Widget示例里有一个下拉框专门用来切日期文本格式。它实际映射的是QCalendarWidget::setDateTextFormat方法而日期显示还会有另一个维度那就是Qt::DateFormat枚举比如Qt::TextDate会把日期显示成“2025年2月14日”的长文本Qt::ISODate则是“2025-02-14”这种机器友好的格式。很多朋友在做国际化软件时会在日期显示上踩坑——明明系统是中文环境控件右下方文本却显示英文格式。这多半是因为程序里没设置QLocale或者用了默认的C locale。具体到QCalendarWidget它的表头显示和日期网格中“周一”“二月”这类文字是可以跟随系统语言环境自动切换的。但前提是你在main函数里得做两件事第一通过QTranslator加载对应的qt_zh_CN.qm翻译文件第二设置QLocale::setDefault(QLocale(QLocale::Chinese, QLocale::China))。如果你做的是跨平台软件还要注意Windows和Linux的本地化目录结构有差异WIndows上qm文件一般在Qt安装目录的translations文件夹里而Linux发行版有的放在/usr/share/qt5/translations。示例自带的Demo没做这个处理因为演示程序可以默认英文但我们自己开发应用时要记得补上。再延伸一个细节QCalendarWidget的日期文本格式还可以区分“上旬/中旬/下旬”的前景、背景色。示例里有一块代码演示了怎么用QTextCharFormat给日期设置不同的前景色、背景色甚至加粗。这个特性不单单是“好看”排班表、打卡记录、股票K线日历标记都用得上。比如你在一个考勤系统里把周末的日期的背景色设为浅灰色把旷工的日期设成浅红色用户一眼就能看出来这个月哪几天有问题。这个能力背后的原理是QCalendarWidget在绘制每个日期格子时会去查一张“日期格式映射表”如果当前日期在表里就用指定格式去绘制否则就用默认格式。所以你要做的就是往这张表里填数据QMapkey是QDatevalue是QTextCharFormat。需要注意QMap的键值排序特性当你批量标记一个月的大量日期时最好使用QHash或者按时间顺序插入虽然QMap也能用但使用QHash的效率会稍微好一些。3.3 选择模式与日期范围限制示例里右侧的单选框组分别对应三个选择模式单选、无选择、多选。实际开发中单选用得最多无选择适合只做展示不允许交互的日历视图多选模式适合需要一次圈定多个日期范围的场景比如酒店预订要选择连续多个夜晚或者报表系统要选择多个统计日期。日期范围限制是QCalendarWidget非常典型的业务能力它对应setMinimumDate和setMaximumDate两个接口。如果你想做“只能选今天之前”或“只能选今天之后”的效果用这两个接口最简单。但要注意最小和最大日期之间包含首尾两端判断逻辑是闭区间。换言之如果你设了minimumDate为今天那么今天也是可以被选中的如果希望只能选明天以后最小值应该改成QDate::currentDate().addDays(1)。这种边界条件在需求评审时就必须跟产品讲清楚否则就会出现“昨晚我明明能选今天上线后选不了了”这种看似奇怪的现象。配合日期范围的还有内部日历网格翻页边界的控制如果你设置了最小值网格的翻页不会阻止用户翻到比最小值更早的月份只是那几个月里的日期全部不可选中。对某些要求严格的业务场景比如不能开放查询系统运行日志之前的日期这种表现可能不够理想这时需要自行监听页面变更事件再根据当前页与范围限制的关系决定是否把页面强制拉回合法范围内。4. 动手改造围绕示例做三个可落地的小项目看示例、跑示例最终目的还是为了内化成自己的开发能力。我建议每个读过这篇的朋友做完上面的基础操作后再花半天时间给它做三个方向的改造。一个方向是完善选择时的反馈一个方向是视觉层面的定制第三是业务层面的存储联动。这三个方向做完你对QCalendarWidget的掌握程度会有本质的提升。4.1 改造一做一个自定义日期选择器示例自带的是一个单日历面板但实际办公系统里经常需要带“开始日期”和“结束日期”的双日历选择。用QCalendarWidget来做这套并不复杂把两个日历控件水平排开左侧选开始日期右侧选结束日期再在两者之间画一个箭头表示区间。难点在于处理两个日历之间的逻辑约束结束日期不能早于开始日期。我的做法是在左侧日历的selectionChanged信号里判断当前选中日期是否晚于右侧的当前值如果是则忽略这次选择或者在选择后自动把右侧日期同步成同一天。同时把左侧日历的maximumDate临时设置为右侧日历当前选中日期的前一天这样用户就算想点后面的日期也点不到了。// 伪代码示意左侧日历不能选择晚于右侧日期的天数 connect(calendarLeft, QCalendarWidget::selectionChanged, this, [this]() { QDate leftDate calendarLeft-selectedDate(); QDate rightDate calendarRight-selectedDate(); if (leftDate rightDate) { calendarLeft-setSelectedDate(rightDate); return; } calendarRight-setMinimumDate(leftDate); });实际做的时候要注意防抖用户在左侧日历上快速连续点击可能会触发多次selectionChanged如果每次都去设置右侧日历的minimumDate会引发一系列无谓的界面刷新。我的解决方案是加一个标志位或者比较QDate对象是否变化了再决定要不要往下走。这个小改造做完你对“跨控件数据联动”和“防止信号风暴”这两个概念就会特别有感觉。4.2 改造二给日期着色实现排班表排班表和打卡记录最需要视觉化呈现。QCalendarWidget的setDateTextFormat就是为此设计的。操作步骤很直白把员工的排班规则存到QMap里然后编程遍历这个月的每一天根据规则给对应的日期设置QTextCharFormat。比如白班是蓝色文本加白底夜班是黄色文本加深色底休息日直接置灰。QMapQDate, QTextCharFormat formats; QTextCharFormat nightShiftFormat; nightShiftFormat.setBackground(QColor(230, 184, 138)); nightShiftFormat.setForeground(QColor(128, 0, 0)); nightShiftFormat.setFontWeight(QFont::Bold); formats.insert(date, nightShiftFormat); calendarWidget-setDateTextFormat(formats);这里有个坑要提醒setDateTextFormat这个接口的作用不是累加式添加而是覆盖式赋值。每次调用这个方法内部日期格式映射表会整体替换成你传入的QMap。如果你今天传的是白班格式表明天传的是夜班格式表被覆盖掉的日期就会恢复成默认样式。所以正确做法是每次刷新时用当前月份所有需要特殊标注的日期重新构建一个完整的QMap再一次性set进去。我做排班模块时踩过一次这个坑排查了好久才发现前面设置的周末颜色莫名消失了就是因为这个覆盖机制。除了颜色QCalendarWidget还允许隐藏垂直表头显示周数的那一列对排班表来说这一列会占宽度也容易让人误以为是工号建议直接用setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader)干掉。4.3 改造三一个极简日历记事本把QCalendarWidget和一款纯文本备忘录结合是很经典的应用模式。核心需求是用户选中某一天可以在右侧文本框里写内容写完自动保存再次切换到某一天时如果当天有记录文本框中自动载入。实现思路如下用QHash存储“日期-内容”映射QDate做键QString做内容。日历的selectionChanged信号触发读取函数从哈希表里找出选中日期的内容填充到QTextEdit。在QTextEdit的textChanged信号或者保存按钮的clicked信号里把当前内容写回哈希表。退出程序时把哈希表用QJsonDocument序列化写到本地JSON文件。这个Demo写起来不超过150行代码但里面已经覆盖了状态管理、界面刷新、本地持久化三个核心模块。如果你还想升级可以把QTextEdit换成QListView每选中一天就列出当天的多条记录这就无限接近一个完整的日程管理软件雏形了。注意用QHash存日期时建议统一用QDate对象本身做key不要用toString(yyyy-MM-dd)的字符串。字符串做key在查询时有格式化开销还会遇到时间格式不统一引发的隐性问题。QDate做key直接用匹配稳、性能好跨平台行为也一致。5. 调试经验与常见问题排查实录5.1 个性化样式失效怎么办很多人从示例里看到了QCalendarWidget有改日期颜色的能力就想着用QSSQt样式表把所有日子统一改颜色。实际操作时往往会碰到设置了QCalendarWidget QAbstractItemView { background-color: ... }结果只有边框变了格子颜色没变。原因在于QCalendarWidget内部多级结构很复杂日期网格本身是由一个Viewport和一个内部Model共同完成绘制的用QSS去直接改背景色动的只是最外层QAbstractScrollArea的视口背景真正绘制日期文字的cell区域并不会被这个QSS影响。在QCalendarWidget里设置样式正确方案是优先用setDateTextFormat配合QTextCharFormat它才是针对“单个日期格子”的视觉定制接口。想改整个控件大背景可以用setGridVisible来显示网格线条网格的样式由palette调色板控制。真到了需要完全重绘的地步那就得走子类化路线重写paintCell方法。这个方法的签名是void paintCell(QPainter *painter, const QRect rect, const QDate date) const; 在里面你可以完全掌控日期格子的绘制逻辑背景、边框、文字、甚至过期日期的置灰效果都由你自己画。示例里是没有展示这个高级玩法的但作为爱好者和专业人士值得去了解。5.2 日期格式显示不对与本地化问题如果你按示例代码自己新建工程发现月份标题显示的是英文“February”而不是“二月”第一反应不要猜是系统语言问题要看程序里有没有加载翻译文件。Qt自带的翻译文件路径在Windows下通常在“Qt安装目录/translations/qt_zh_CN.qm”。加载的代码就三行QTranslator translator; translator.load(:/qt_zh_CN.qm); app.installTranslator(translator);值得注意的是translator对象必须保持存活如果定义在main函数内部并且作用域很小可能加载动画一闪即失而某些控件尤其是已经实例化过的QCalendarWidget不会主动重绘翻译后的文字。正确的做法是把translator定义在main函数作用域靠外的地方、或者作为全局变量/静态成员然后重新设置一次QLocale才不会出现切换无效的诡异现象。我自己在Linux环境部署时遇到过加载了qt_zh_CN.qm后周几仍是英文最终排查发现是编译时没有把qm文件放进资源文件程序运行时找不到当地文件。这种情况可以用绝对路径拼一个QLibraryInfo::location(QLibraryInfo::TranslationsPath)来定位Windows和Linux上这个路径差异挺大。5.3 日期越界与最小最大日期坑一个很常见的需求是禁止用户选择今天之前的日期。新手通常这么写ui-calendarWidget-setMinimumDate(QDate::currentDate());这么写的结果是今天可以选中但这引出一个问题如果你是做“截止日期修改”的模块今天这个日期本身就需要被锁定那就得换成addDays(1)。还有如果你动态调整minimumDate比如用户选择了开始日期后就联动调整结束日期的最小值务必注意调整完日期范围后再主动调用一次setSelectedDate把当前不合法选区移到一个合法位置上。否则会发生这样的情况当前选中日期已经早于新的minimumDate控件会显示选中了某个不可用日期内部状态和界面显示不一致后续信号的触发逻辑会变得很怪。另外如果设置的最小日期晚于当前显示页面里的日期QCalendarWidget并不会自动把页面翻到最小日期所在的月份。这个问题我之前在做一个内部借书系统时遇到后来不得不手动调用setCurrentPage(minimumDate.year(), minimumDate.month())这个行为官方文档其实写得很含糊非常容易被忽略。5.4 信号重复触发的排查套路QCalendarWidget的信号问题也值得一提。selectionChanged和currentPageChanged都会在某些操作下连续触发多次。比如你调用setSelectedDate时如果日期已经就是当前选中日期那不会触发但只要日期变化一次必然触发一次selectionChanged。如果某个槽函数里又去调用了setMinimumDate或setMaximumDate而这些方法内部又会经过选择状态的合法性检测就可能再次触发selectionChanged。如果你在槽里做了弹窗或者日期重设就很容易陷入递归套娃。面对这种问题我的排查惯例是在槽函数第一行打印一行日志记录触发值和当前控件内部状态。确认出现重复触发后在槽外设一个成员变量m_updatingFlag在关键操作前置true槽函数入口判断这个标志为真就直接return。这是一种防止重入的经典做法写Qt程序经常会用到不只是日历控件。5.5 垂直表头与周数的显示日历左侧的垂直表头显示的是周数。默认情况下它会占据一部分宽度不少开发者觉得这是多余的。设置setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader)能把宽度完全释放出来但有人发现这样设置后表头确实没了整个网格的宽度也并没有变明显。原因在于QCalendarWidget内部布局中垂直表头仍然在占用最小空间除非你同时处理viewport的宽度或者调整日历控件的最小宽度。实际上我的做法是把日历控件的minimumWidth设置成比原始尺寸大几十像素让网格部分真正受益。如果你连表头空间都不想残留可以试试把verticalHeaderFormat设为ISOWeekNumber这样和周数文本同时显示界面上看反而更整齐。6. 写在最后看完示例之后还能怎么练这个标题下的项目本身不大但强调举一反三之后它对进阶的价值就非常高了。建议你按我前面说的三个改造方向自己挑一个动手写一写。代码量不多但足以把QCalendarWidget从“会用”变成“能用明白”。按我个人的经验最容易被忽略的不是API本身而是它和业务逻辑结合时的各种边界情况——日期时间处理永远是最容易出隐藏BUG的领域。回想早期我在一个内部工具里用QCalendarWidget做截止日期选择结果用户反馈说“选了28号以后日期就消失了”排查了半天才发现是触发了日期范围限制和页面刷新之间的次序问题。后来我把所有跟日期相关的设置集中在了一个统一刷新函数里这个BUG就再也没出现过。所以这里也特别想提醒读到这里的你如果你在改造Calendar Widget的过程中遇到了日期跳跃、选中状态丢失、面板宽度塌缩这类的怪问题优先往“日期范围变更后没有主动刷新当前页”这个方向去排查。如果你跑通这个示例之后还想往更深的方向探索下一步可以试试做一个带农历显示的自绘日历或者把日期网格替换成可拖拽事件块的任务面板。前者难度在于农历数据和paintCell绘制的配合后者则需要在QCalendarWidget基础上自定义内部布局这已经是另一个量级的技术挑战了。最后分享一个我坚持了很久的总结习惯每次看完Qt官方示例都在工程目录里写一个README记录这个示例能不能迁移到老版本、哪些API已经被标记为过时、哪些交互细节不符合实际业务习惯。这些笔记在几个月后回头翻看往往比重新查一遍文档更有用。日历这个控件不复杂但正是这类“不复杂”的组件能帮你把Qt的布局系统、信号槽机制、本地化处理和自绘逻辑全部串起来值得沉下心来消化。
RELATED

相关推荐

Electron打包HTML为桌面应用:全屏隐藏任务栏+Esc退出+自定义图标

Electron打包HTML为桌面应用:全屏隐藏任务栏+Esc退出+自定义图标

简介:本资源是一套基于Electron框架将HTML网页打包为Windows可执行程序(.exe)的完整实践方案,面向前端开发者、桌面应用入门学习者及需快速交付轻量级本地化网页应用的技术人员。内容覆盖全屏启动、任务栏隐藏、Esc键退出、自定义…

📅 2026/10/14 18:15:10
Qt手动解析WAV实现高精度波形与频谱可视化

Qt手动解析WAV实现高精度波形与频谱可视化

简介:本资源是一个基于Qt框架实现WAV音频文件波形图与频谱图可视化显示的完整C项目,面向Qt初学者、音视频开发入门者及GUI图形编程学习者,解决音频数据解析、时频域可视化呈现等典型工程问题。压缩包共9个文件,含3个核心cpp源码&a…

📅 2026/10/14 18:15:10
2026天津创业者公司注册办理指南:常见坑点梳理与合规机构选择建议

2026天津创业者公司注册办理指南:常见坑点梳理与合规机构选择建议

天津创业注册公司的行业背景天津靠海,做外贸和跨境生意的创业者多,开公司的需求一直不小。但真要把营业执照拿到手、后续记账报税跟得上,不少人会卡在流程细节上。要么材料准备不全来回跑,要么注册地址选不对影响后续办税&#xf…

📅 2026/10/14 18:15:10
MORE NEWS

更多资讯

📰

外呼系统的作用

外呼系统(Outbound Call System)是基于运营商正规线路、结合呼叫中心与 CRM 客户管理能力的云通信工具,帮助企业规模化、规范化地开展电话营销、客户回访与售后服务。与传统的手机手动拨号相比,外呼系统真正解决的是 “打得出去、…

📰

PyPI 私有源怎么用:从安装到 twine 上传和 pip 安装

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

数学专业小白必看:8个月转行AI大模型,收藏这份实战路线图

本文针对数学专业学生,指出传统数学知识在AI行业应用有限,建议转行AI大模型领域。文章提供了四步转行路径:重建CS基础(数据结构、算法、Python等);掌握大模型技术栈(Transformer架构、部署工具、…

📰

服装AI质检数据存储架构:近期数据与历史数据为何要分开存?

在服装AI质检场景中,每天都会产生海量的检测数据——包括图像、检测结果、缺陷标注、设备运行日志等。这些数据既需要支撑实时业务查询(如当日质检报表、缺陷趋势监控),又需要长期留存以满足追溯、审计和模型迭代需求。 一个常见的…

📰

2026-10-13:创建一个恰好有 K 条路径的网格图Ⅰ。用go语言,有 m、n、k 三个整数。请生成一个 m 行 n 列的字符矩阵,每个位置只能填“.”或“#”。其中“.”表示可以经过的格子,“#

2026-10-13:创建一个恰好有 K 条路径的网格图Ⅰ。用go语言,有 m、n、k 三个整数。请生成一个 m 行 n 列的字符矩阵,每个位置只能填“.”或“#”。其中“.”表示可以经过的格子,“#”表示不能经过的障碍。所谓有效路线,…

📰

合规数据可视化与PHP后端实战:构建彩票数据管理系统

简介:PHP模拟私彩程序平台源码包,由作者小满制作,面向具备一定PHP基础、希望了解彩票业务逻辑与Web交互开发的读者。项目使用原生PHP构建,核心功能涵盖投注、开奖、结果展示、奖金计算及用户账户管理,并配有页面样式与…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬