一、前言

农历控件在国产linux中必备的控件之一,毕竟要适应国人的习惯,你看win10系统的日历,现在点开来直接就有农历在上面,非常方便人性化,所以在很多用Qt做的项目中,也有农历控件的应用场景,而Qt自带的日历控件比较简单,仔细看过源码的人也只知道,其实就是一堆微调框,下拉框,表格组成的,于是打算借用此方法造一个农历控件,本控件的算法是倪大侠提供的,个人测试下来还是没有问题的,造这个农历控件最大的难点是如何根据日期计算农历时间,再加上一些农历的节气之类的,这个网上估计也有很多的算法参考。

主要功能:

  1. 可设置边框颜色/周末颜色/角标颜色/农历节日颜色
  2. 可设置当前月文字颜色/其他月文字颜色/选中日期文字颜色/悬停日期文字颜色
  3. 可设置当前月农历文字颜色/其他月农历文字颜色/选中日期农历文字颜色/悬停日期农历文字颜色
  4. 可设置当前月背景颜色/其他月背景颜色/选中日期背景颜色/悬停日期背景颜色
  5. 可设置三种选中背景模式,矩形背景+圆形背景+图片背景
  6. 可直接切换到上一年/下一年/上一月/下一月/转到今天
  7. 可设置是否显示农历信息,不显示则当做正常的日历使用
  8. 支持1900年-2099年范围
  9. 很方便改成多选日期

二、代码思路

void LunarCalendarItem::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //绘制背景和边框
drawBg(&painter); //优先绘制选中状态,其次绘制悬停状态
if (select) {
drawBgCurrent(&painter, selectBgColor);
} else if (hover) {
drawBgCurrent(&painter, hoverBgColor);
} //绘制日期
drawDay(&painter); //绘制农历信息
drawLunar(&painter);
} void LunarCalendarItem::drawBg(QPainter *painter)
{
painter->save(); //根据当前类型选择对应的颜色
QColor bgColor = currentBgColor;
if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
bgColor = otherBgColor;
} painter->setPen(borderColor);
painter->setBrush(bgColor);
painter->drawRect(rect()); painter->restore();
} void LunarCalendarItem::drawBgCurrent(QPainter *painter, const QColor &color)
{
int width = this->width();
int height = this->height();
int side = qMin(width, height); painter->save(); painter->setPen(Qt::NoPen);
painter->setBrush(color); //根据设定绘制背景样式
if (selectType == SelectType_Rect) {
painter->drawRect(rect());
} else if (selectType == SelectType_Circle) {
int radius = side / 2 - 3;
painter->drawEllipse(QPointF(width / 2, height / 2), radius, radius);
} else if (selectType == SelectType_Triangle) {
int radius = side / 3;
QPolygon pts;
pts.setPoints(3, 1, 1, radius, 1, 1, radius);
painter->drawRect(rect());
painter->setBrush(superColor);
painter->drawConvexPolygon(pts);
} else if (selectType == SelectType_Image) {
//等比例缩放居中绘制
QImage img(bgImage);
if (!img.isNull()) {
img = img.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
int x = (width - img.width()) / 2;
int y = (height - img.height()) / 2;
painter->drawImage(x, y, img);
}
} painter->restore();
} void LunarCalendarItem::drawDay(QPainter *painter)
{
int width = this->width();
int height = this->height();
int side = qMin(width, height); painter->save(); //根据当前类型选择对应的颜色
QColor color = currentTextColor;
if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
color = otherTextColor;
} else if (dayType == DayType_WeekEnd) {
color = weekColor;
} if (select) {
color = selectTextColor;
} else if (hover) {
color = hoverTextColor;
} painter->setPen(color); if (showLunar) {
QFont font;
font.setPixelSize(side / 2.7);
painter->setFont(font); QRect dayRect = QRect(0, 0, width, height / 1.7);
painter->drawText(dayRect, Qt::AlignHCenter | Qt::AlignBottom, QString::number(date.day()));
} else {
QFont font;
font.setPixelSize(side / 2);
painter->setFont(font); QRect dayRect = QRect(0, 0, width, height);
painter->drawText(dayRect, Qt::AlignCenter, QString::number(date.day()));
} painter->restore();
} void LunarCalendarItem::drawLunar(QPainter *painter)
{
if (!showLunar) {
return;
} int width = this->width();
int height = this->height();
int side = qMin(width, height); painter->save(); //判断当前农历文字是否节日,是节日且是当月则用农历节日颜色显示
bool exist = (!listDayName.contains(lunar) && dayType != DayType_MonthPre && dayType != DayType_MonthNext); //根据当前类型选择对应的颜色
QColor color = currentLunarColor;
if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
color = otherLunarColor;
} if (select) {
color = selectTextColor;
} else if (hover) {
color = hoverTextColor;
} else if (exist) {
color = lunarColor;
} painter->setPen(color); QFont font;
font.setPixelSize(side / 5);
painter->setFont(font); QRect lunarRect(0, height / 2, width, height / 2);
painter->drawText(lunarRect, Qt::AlignCenter, lunar); painter->restore();
}

三、效果图

四、开源主页

  • 以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。
  • 本开源项目已经成功升级到V2.0版本,分门别类,图文并茂,保你爽到爆。
  • Qt开源武林秘籍开发经验,看完学完,20K起薪,没有找我!
  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 开源秘籍:https://gitee.com/feiyangqingyun/qtkaifajingyan
  4. 个人主页:https://qtchina.blog.csdn.net/
  5. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/

Qt开源作品30-农历控件的更多相关文章

  1. 开源框架之TAB控件

    我的开源框架之TAB控件   需求 (1)支持iframe.html.json格式的tab内容远程请求 (2)支持动态添加tab (3)支持远程加载完成监听,支持tab激活事件监听 (4)支持relo ...

  2. Android开源的精美日历控件,热插拔设计的万能自定义UI

    Android开源的精美日历控件,热插拔设计的万能自定义UI UI框架应该逻辑与界面实现分离,该日历控件使用了热插拔的设计 ,简单几步即可实现你需要的UI效果,热插拔的思想是你提供你的实现,我提供我的 ...

  3. [转]几个开源的.net界面控件

    转自原文 几个不错的开源的.net界面控件,介绍几个自己觉得不错的几个开源的.net界面控件. DockPanel Suite:开发类似VS.net的界面,#Develop就是使用的这个控件. 网址: ...

  4. 基于Qt的第三方库和控件

    ====================== 基于Qt的第三方库和控件 ======================     libQxt --------   http://dev.libqxt.o ...

  5. Qt 界面使用自己定义控件 "提升为"

    1.效果图 我做了一个很easy的样例,一个能够显示颜色的QLabel,边上有个button,点击,跳出颜色选取的Dialog,然后选择一个颜色.这个QLabel会变成什么颜色. 2.ColorLab ...

  6. 几个不错的开源的.net界面控件

    转自原文 几个不错的开源的.net界面控件 (转) 几个不错的开源的.net界面控件 - zt 介绍几个自己觉得不错的几个开源的.net界面控件,不知道是否有人介绍过. DockPanel Suite ...

  7. qt 在ui界面添加控件后在cpp文件中无法调用?

    问题:qt 在ui界面添加控件后在cpp文件中无法调用? 解决方法:在build选项中选择“重新build项目”,再次在cpp中调用添加的控件发现可以调用了. 还有一种情况导致添加控件后无法调用,就是 ...

  8. PyQt(Python+Qt)学习随笔:布局控件layout的layoutSizeConstraint属性不起作用的问题解决办法

    在<PyQt(Python+Qt)学习随笔:布局控件layout的layoutSizeConstraint属性>中介绍layout的layoutSizeConstraint属性后,反复测试 ...

  9. Qt QTableView 表格内添加控件

    目录 Qt QTableView 表格内添加控件 1. QItemDelegate 2. setIndexWidget 3. setIndexWidget + setLayout Qt QTableV ...

  10. Qt编写的项目作品1-自定义控件大全

    一.功能特点 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的控件数量. 每个类都可以 ...

随机推荐

  1. 内核级流量治理引擎Kmesh八大新特性解读

    本文分享自华为云社区<内核级流量治理引擎 Kmesh v0.5 发布!进击的Sidecarless服务网格>,作者:云容器大未来. 我们非常高兴地宣布 Kmesh v0.5.0 的发布.首 ...

  2. Vmware挂载san存储_vSphere 6.x 共享存储LUN丢失分区表修复(精华)

    Vmware挂载san存储_vSphere 6.x 共享存储LUN丢失分区表修复 炎炎夏夜客户机房空调意外故障,前端ESXI物理服务器由于温度过高都自保关机,存储和SAN没有自保关机.上班修复空调后, ...

  3. 使用 KubeSphere 实现微服务的灰度发布

    前言 今天来说一说,在 KubeSphere 中两个 " 小姐姐 " 如何来回切换,这是什么意思哩?其实就是互联网产品中常用的灰度发布方式. 互联网产品需要快速迭代上线,既要保证新 ...

  4. Java 线程池获取池中所有线程列表的方法

    在Java中,获取线程池中所有线程列表并不是一个直接支持的功能,因为线程池的设计通常是为了隐藏和管理底层的线程细节,从而提供更高层次的抽象和并发控制能力.然而,通过一些反射和技巧,我们仍然可以获取到线 ...

  5. 专访|开源之夏最佳质量奖 Apache RocketMQ Committer 黄章衡

    随着开源之夏2022年度优秀学生名单出炉,其中Apache RocketMQ Committer 黄章衡同学获得开源之夏最佳质量奖.今天,我们也带来黄章衡同学的人物专访. https://summer ...

  6. 人口分析实战(利用jupyter)

    目录 1.项目需求 2.开始操作 2.1导入我们所需要的包 2.2导入数据.查看原始数据 2.3对数据进行清洗 2.4对数据进行处理 1.项目需求 需求: 导入文件,查看原始数据 将人口数据和各州简称 ...

  7. React 防抖(Debounce)Hook

    防抖动 (debounce)是常见的需求,那么如何搭配 React Hooks 实现防抖动呢,下面演示两种方案. 方案一 副作用防抖 /** * * @param {React.EffectCallb ...

  8. MaskGCT,AI语音克隆大模型本地部署(Windows11),基于Python3.11,TTS,文字转语音

    前几天,又一款非自回归的文字转语音的AI模型:MaskGCT,开放了源码,和同样非自回归的F5-TTS模型一样,MaskGCT模型也是基于10万小时数据集Emilia训练而来的,精通中英日韩法德6种语 ...

  9. 常见return错误

    常见return错误 3221225477 (0xC0000005): 访问越界,一般是读或写了野指针指向的内存. 3221225725 (0xC00000FD): 堆栈溢出,一般是无穷递归造成的. ...

  10. PHP word PDF excel 文档互转 预览 (linux libreoffice)

    1--卸载系统当前的libreoffice 执行如下命令:yum remove libreoffice-* 2--为了能使用镜像,在etc  目录之下的hosts文件内加入代理. 注意没有加的话,可能 ...