一、前言

操作系统的更新迭代速度非常快,基本上三五年就有个新版本出来,WIN10操作系统还是一个比较成功的系统,据说现在市场份额越来越大,XP的份额已经很小,WIN7的份额也在逐步减少,在最新的WIN10系统中,右下角有个日历控件,还是自带农历的,这个本地化做的蛮好的,鼠标移上去还有光晕背景效果,体验非常赏心悦目,于是打算用Qt也高仿一个。

本控件的技术难点有两个,一个是根据当前月份自动排列星期和日期,这个需要自动计算的,难点二是绘制光晕背景,需要用到painter中的图像叠加模式setCompositionMode,设置好图像叠加模式以后,可以将多个绘制重叠,按照设定的规则组合,比如将光晕背景绘制在背后。

二、实现的功能

  • 1:可设置背景颜色
  • 2:可设置光晕颜色
  • 3:可设置文字颜色
  • 4:可设置选中日期背景
  • 5:光晕跟随鼠标移动

三、效果图

四、头文件代码

#ifndef SHADOWCALENDAR_H
#define SHADOWCALENDAR_H /**
* 光晕日历控件 作者:雨田哥(QQ:3246214072) 整理:feiyangqingyun(QQ:517216493) 2019-10-07
* 1:可设置背景颜色
* 2:可设置光晕颜色
* 3:可设置文字颜色
* 4:可设置选中日期背景
* 5:光晕跟随鼠标移动
*/ #include <QWidget>
#include <QDate> #ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif class QDESIGNER_WIDGET_EXPORT ShadowCalendar : public QWidget
#else
class ShadowCalendar : public QWidget
#endif {
Q_OBJECT
Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)
Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
Q_PROPERTY(QColor shadowColor READ getShadowColor WRITE setShadowColor)
Q_PROPERTY(QColor selectColor READ getSelectColor WRITE setSelectColor) public:
struct DateItem {
int year;
int month;
int day; DateItem()
{
year = -1;
month = -1;
day = -1;
}
}; explicit ShadowCalendar(QWidget *parent = 0);
~ShadowCalendar(); public:
void updateCalendar(const QDate &selectDate); protected:
void leaveEvent(QEvent *);
void mouseMoveEvent(QMouseEvent *);
void paintEvent(QPaintEvent *); private:
QColor bgColor; //背景颜色
QColor textColor; //文字颜色
QColor shadowColor; //光晕颜色
QColor selectColor; //选中颜色 QDate selectDate; //今天日期
DateItem dateItem[6][7]; //日期数组 public:
QColor getBgColor() const;
QColor getTextColor() const;
QColor getShadowColor() const;
QColor getSelectColor() const; QSize sizeHint() const;
QSize minimumSizeHint() const; public Q_SLOTS:
//设置背景颜色+文字颜色+光晕颜色+选中颜色
void setBgColor(const QColor &bgColor);
void setTextColor(const QColor &textColor);
void setShadowColor(const QColor &shadowColor);
void setSelectColor(const QColor &selectColor);
}; #endif // SHADOWCALENDAR_H

五、核心代码

void ShadowCalendar::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing); int sw = 336;
int sh = 336;
qreal scaleX = this->width() * 1.0 / sw;
qreal scaleY = this->height() * 1.0 / sh; painter.scale(scaleX, scaleY);
painter.setPen(Qt::NoPen);
painter.fillRect(0, 0, sw, sh, bgColor); qreal iw = sw / 7.0;
qreal ih = sh / 7.0; //mask
QPointF globalpoint = this->mapFromGlobal(QCursor::pos());
const QPointF &point = QPointF(globalpoint.x() / scaleX, globalpoint.y() / scaleY); //绘制光晕背景
if (this->underMouse()) {
int effectradius = 58;
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
QRadialGradient radialGrad(point, effectradius);
radialGrad.setColorAt(0, QColor(0, 0, 0, 120));
radialGrad.setColorAt(1, QColor(0, 0, 0, 255));
painter.setBrush(radialGrad);
painter.drawEllipse(point, effectradius, effectradius); painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
painter.setBrush(Qt::NoBrush); for (int row = 0; row < 6; row++) {
for (int column = 0; column < 7; column++) {
QRectF rect = QRectF(column * iw, (row + 1) * ih, iw, ih).adjusted(3, 3, -3, -3);
if (rect.contains(point)) {
painter.save();
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.setPen(QPen(QColor(220, 220, 220, 160), 2));
painter.drawRoundedRect(rect, 2, 2);
painter.restore();
continue;
} else {
painter.setPen(QPen(shadowColor, 2));
} painter.drawRoundedRect(rect, 2, 2);
}
} //绘制圆形的光晕底层背景
painter.fillRect(0, 0, sw, sh, QColor(200, 200, 200, 50));
} //绘制头部中文数字,先设置图像叠加模式为源在上面
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.setPen(textColor);
QStringList listHead;
listHead << "一" << "二" << "三" << "四" << "五" << "六" << "日";
for (int i = 0; i < 7; i++) {
painter.drawText(i * iw, 0, iw, ih, Qt::AlignCenter, listHead.at(i));
} //绘制日期
for (int row = 0; row < 6; row++) {
for (int column = 0; column < 7; column++) {
if (dateItem[row][column].day > 0) {
QRectF rect = QRectF(column * iw, (row + 1) * ih, iw, ih).adjusted(3, 3, -3, -3); //如果是选中的日期则突出绘制背景
if (QDate::currentDate() == QDate(dateItem[row][column].year, dateItem[row][column].month, dateItem[row][column].day)) {
painter.setPen(QPen(selectColor, 2));
painter.setBrush(Qt::NoBrush); //如果和光晕效果重叠则边框高亮
if (rect.contains(point)) {
painter.setPen(QPen(selectColor.lighter(), 2));
} //绘制圆角边框
painter.drawRoundedRect(rect, 2, 2); //绘制里边背景
painter.setPen(Qt::NoPen);
painter.setBrush(selectColor);
painter.drawRoundedRect(rect.adjusted(4, 4, -4, -4), 2, 2);
} painter.setPen(textColor);
painter.drawText(rect, Qt::AlignCenter, QString::number(dateItem[row][column].day));
}
}
}
}

六、控件介绍

  1. 超过160个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
  2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
  3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.13的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
  4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
  5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
  6. 每个控件默认配色和demo对应的配色都非常精美。
  7. 超过130个可见控件,6个不可见控件。
  8. 部分控件提供多种样式风格选择,多种指示器样式选择。
  9. 所有控件自适应窗体拉伸变化。
  10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
  11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
  12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
  13. 所有控件最后生成一个动态库文件(dll或者so等),可以直接集成到qtcreator中拖曳设计使用。
  14. 目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。
  15. 自定义控件插件开放动态库使用(永久免费),无任何后门和限制,请放心使用。
  16. 目前已提供32个版本的dll,其中qt_5_7_0_mingw530_32这个版本会一直保证最新的完整的。
  17. 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
  18. Qt入门书籍推荐霍亚飞的《Qt Creator快速入门》《Qt5编程入门》,Qt进阶书籍推荐官方的《C++ GUI Qt4编程》。
  19. 强烈推荐程序员自我修养和规划系列书《大话程序员》《程序员的成长课》《解忧程序员》,受益匪浅,受益终生!
  20. SDK地址:https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk

Qt编写自定义控件65-光晕日历的更多相关文章

  1. Qt编写自定义控件二动画按钮

    现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原 ...

  2. Qt编写自定义控件66-光晕时钟

    一.前言 在上一篇文章写了个高仿WIN10系统的光晕日历,这次来绘制一个光晕的时钟,也是在某些网页上看到的效果,时分秒分别以进度条的形式来绘制,而且这个进度条带有光晕效果,中间的日期时间文字也是光晕效 ...

  3. Qt编写自定义控件10-云台仪表盘

    前言 做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程 ...

  4. Qt编写自定义控件70-扁平化flatui

    一.前言 对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反 ...

  5. Qt编写自定义控件16-魔法老鼠

    前言 五一期间一直忙着大屏电子看板软件的开发,没有再去整理控件,今天已经将大屏电子看板的所有子窗口都实现了任意停靠和双击独立再次双击最大化等功能,过阵子有空再写一篇文章介绍其中的技术点.魔法老鼠控件, ...

  6. Qt编写自定义控件插件开放动态库dll使用(永久免费)

    这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本 ...

  7. Qt编写自定义控件11-设备防区按钮控件

    前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...

  8. Qt编写自定义控件9-导航按钮控件

    前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有的CSS2 ...

  9. Qt编写自定义控件8-动画按钮组控件

    前言 动画按钮组控件可以用来当做各种漂亮的导航条用,既可以设置成顶部底部+左侧右侧,还自带精美的滑动效果,还可以设置悬停滑动等各种颜色,原创作者雨田哥(QQ:3246214072),驰骋Qt控件界多年 ...

随机推荐

  1. java设计模式解析(1) Observer观察者模式

      设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...

  2. c++的动态绑定和静态绑定及多态的实现原理(摘)

    C++多态的实现原理 为了支持c++的多态性,才用了动态绑定和静态绑定.理解它们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误. 需要理解四个名词:对象的静态类型:对象在声明时采用的类型. ...

  3. go实现文件的上传

    上传端 send.go package main import ( "fmt" "io" "net" "os") fun ...

  4. [CodeForces - 906D] Power Tower——扩展欧拉定理

    题意 给你 $n$ 个 $w_i$ 和一个数 $p$,$q$个询问,每次询问一个区间 $[l,r] $,求 $w_l ^{w_{l+1}^{{\vdots}^{w_r}}} \ \% p$ 分析 由扩 ...

  5. debug错误总结

    1, 2,就是一个大括号的问题..让你总是得不了满分..明明和别人的代码差不多. 3,就比如P1914,这种藏坑的题,或者说这一类藏坑的题. 坑是什么呢?就是位数不够往后推的时候.. 你不填坑你就得不 ...

  6. Kubernetes 学习25 创建自定义chart及部署efk日志系统

    一.概述 1.我们说过在helm架构中有这么几个关键组件,helm,tiller server,一般托管运行于k8s之上,helm能够通过tiller server在目标k8s集群之上部署应用程序,而 ...

  7. 【CSS】Table样式

    一.table td的宽度详解 Table只有Table的宽度是可以设置的,并且各个浏览器理解一致 原则上应该将table的宽度设置成一个固定的值,而不应该设置成一个根据屏幕变化的值 Table的宽度 ...

  8. cube.js 学习(七)cube.js type 以及format 说明

      cube.js 对于measure以及dimension 提供了丰富的数据类型,基本满足我们常见应用的开发,同时对于不同类型也提供了 格式化的操作 measure类型 number 格式 purc ...

  9. http://www.tldp.org/LDP/abs/abs-guide.txt.gz

    http://www.tldp.org/LDP/abs/abs-guide.txt.gz

  10. mobx中的数组需要注意的地方

    mobx中如果将数组作为可观察. 可以通过添加修饰符observable或者调用observable方法. 很多的时候, 我们将此修饰为可观察的对象后, 就随处可用了. 比如,采用 map  forE ...