liudianwu |
2020-06-08 09:07 |
Qt开源作品30-农历控件
## 一、前言 农历控件在国产linux中必备的控件之一,毕竟要适应国人的习惯,你看win10系统的日历,现在点开来直接就有农历在上面,非常方便人性化,所以在很多用Qt做的项目中,也有农历控件的应用场景,而Qt自带的日历控件比较简单,仔细看过源码的人也只知道,其实就是一堆微调框,下拉框,表格组成的,于是打算借用此方法造一个农历控件,本控件的算法是倪大侠提供的,个人测试下来还是没有问题的,造这个农历控件最大的难点是如何根据日期计算农历时间,再加上一些农历的节气之类的,这个网上估计也有很多的算法参考。
**主要功能:**
1. 可设置边框颜色/周末颜色/角标颜色/农历节日颜色 2. 可设置当前月文字颜色/其他月文字颜色/选中日期文字颜色/悬停日期文字颜色 3. 可设置当前月农历文字颜色/其他月农历文字颜色/选中日期农历文字颜色/悬停日期农历文字颜色 4. 可设置当前月背景颜色/其他月背景颜色/选中日期背景颜色/悬停日期背景颜色 5. 可设置三种选中背景模式,矩形背景+圆形背景+图片背景 6. 可直接切换到上一年/下一年/上一月/下一月/转到今天 7. 可设置是否显示农历信息,不显示则当做正常的日历使用 8. 支持1900年-2099年范围 9. 很方便改成多选日期
## 二、代码思路 ```c++ 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(); } ```
## 三、效果图 [attachment=21666]
## 四、开源主页 **以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。**
1. 国内站点:[https://gitee.com/feiyangqingyun/QWidgetDemo](https://gitee.com/feiyangqingyun/QWidgetDemo) 2. 国际站点:[https://github.com/feiyangqingyun/QWidgetDemo](https://github.com/feiyangqingyun/QWidgetDemo) 3. 个人主页:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun) 4. 知乎主页:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/) |
|