一、前言

这个控件没有太多的应用场景,主要就是练手,论美观的话比不上之前发过的一个图片时钟控件,所以此控件也是作为一个基础的绘制demo出现在Qt源码中,我们可以在Qt的安装目录下找到一个时钟控件的绘制,甚至还有qml版本,本控件无非就是一个仪表边框加上时钟分钟刻度再加上时分秒指针,打完收工,我是在此基础上增加了可以设置各种颜色,然后鼠标右键可设置四种效果 普通效果/弹簧效果/连续效果/隐藏效果,弹簧效果的意思是秒钟走动的时候,先移动到超过指定位置,然后又重新弹回来,连续效果的意思是将步长减少,一点点的移动,将秒钟的定时器精度调高。还有一个新增的功能是内置了设置系统时间公共槽函数,支持任意操作系统。

二、实现的功能

  • 1:可设置边框颜色
  • 2:可设置前景色背景色
  • 3:可设置时钟分钟秒钟指针颜色
  • 4:可设置刷新间隔
  • 5:鼠标右键可设置四种效果 普通效果/弹簧效果/连续效果/隐藏效果
  • 6:增加设置系统时间公共槽函数,支持任意操作系统

三、效果图

四、头文件代码

  1. #ifndef GAUGECLOCK_H
  2. #define GAUGECLOCK_H
  3. /**
  4. * 时钟仪表盘控件 作者:feiyangqingyun(QQ:517216493) 2016-10-23
  5. * 1:可设置边框颜色
  6. * 2:可设置前景色背景色
  7. * 3:可设置时钟分钟秒钟指针颜色
  8. * 4:可设置刷新间隔
  9. * 5:鼠标右键可设置四种效果 普通效果/弹簧效果/连续效果/隐藏效果
  10. * 6:增加设置系统时间公共槽函数,支持任意操作系统
  11. */
  12. #include <QWidget>
  13. #ifdef quc
  14. #if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
  15. #include <QtDesigner/QDesignerExportWidget>
  16. #else
  17. #include <QtUiPlugin/QDesignerExportWidget>
  18. #endif
  19. class QDESIGNER_WIDGET_EXPORT GaugeClock : public QWidget
  20. #else
  21. class GaugeClock : public QWidget
  22. #endif
  23. {
  24. Q_OBJECT
  25. Q_ENUMS(SecondStyle)
  26. Q_PROPERTY(QColor crownColorStart READ getCrownColorStart WRITE setCrownColorStart)
  27. Q_PROPERTY(QColor crownColorEnd READ getCrownColorEnd WRITE setCrownColorEnd)
  28. Q_PROPERTY(QColor foreground READ getForeground WRITE setForeground)
  29. Q_PROPERTY(QColor background READ getBackground WRITE setBackground)
  30. Q_PROPERTY(QColor pointerHourColor READ getPointerHourColor WRITE setPointerHourColor)
  31. Q_PROPERTY(QColor pointerMinColor READ getPointerMinColor WRITE setPointerMinColor)
  32. Q_PROPERTY(QColor pointerSecColor READ getPointerSecColor WRITE setPointerSecColor)
  33. Q_PROPERTY(SecondStyle secondStyle READ getSecondStyle WRITE setSecondStyle)
  34. public:
  35. enum SecondStyle {
  36. SecondStyle_Normal = 0, //普通效果
  37. SecondStyle_Spring = 1, //弹簧效果
  38. SecondStyle_Continue = 2, //连续效果
  39. SecondStyle_Hide = 3 //隐藏效果
  40. };
  41. explicit GaugeClock(QWidget *parent = 0);
  42. ~GaugeClock();
  43. protected:
  44. void paintEvent(QPaintEvent *);
  45. void drawCrown(QPainter *painter);
  46. void drawBg(QPainter *painter);
  47. void drawScale(QPainter *painter);
  48. void drawScaleNum(QPainter *painter);
  49. void drawHour(QPainter *painter);
  50. void drawMin(QPainter *painter);
  51. void drawSec(QPainter *painter);
  52. void drawDot(QPainter *painter);
  53. private:
  54. QColor crownColorStart; //外边框渐变开始颜色
  55. QColor crownColorEnd; //外边框渐变结束颜色
  56. QColor foreground; //前景色
  57. QColor background; //背景色
  58. QColor pointerHourColor; //时钟指针颜色
  59. QColor pointerMinColor; //分钟指针颜色
  60. QColor pointerSecColor; //秒钟指针颜色
  61. SecondStyle secondStyle; //秒针走动样式
  62. QTimer *timer; //定时器绘制
  63. int hour, min, sec, msec; //时分秒毫秒
  64. QTimer *timerSpring; //定时器显示弹簧效果
  65. double angleSpring; //弹簧角度
  66. QAction *action_secondstyle; //秒针样式右键菜单
  67. private slots:
  68. void doAction();
  69. void updateTime();
  70. void updateSpring();
  71. public:
  72. SecondStyle getSecondStyle() const;
  73. QColor getCrownColorStart() const;
  74. QColor getCrownColorEnd() const;
  75. QColor getForeground() const;
  76. QColor getBackground() const;
  77. QColor getPointerHourColor() const;
  78. QColor getPointerMinColor() const;
  79. QColor getPointerSecColor() const;
  80. QSize sizeHint() const;
  81. QSize minimumSizeHint() const;
  82. public Q_SLOTS:
  83. //设置秒针走动样式
  84. void setSecondStyle(const SecondStyle &secondStyle);
  85. //设置系统时间
  86. void setSystemDateTime(const QString &year, const QString &month, const QString &day,
  87. const QString &hour, const QString &min, const QString &sec);
  88. //设置外边框渐变颜色
  89. void setCrownColorStart(const QColor &crownColorStart);
  90. void setCrownColorEnd(const QColor &crownColorEnd);
  91. //设置前景色
  92. void setForeground(const QColor &foreground);
  93. //设备背景色
  94. void setBackground(const QColor &background);
  95. //设置时钟指针颜色
  96. void setPointerHourColor(const QColor &pointerHourColor);
  97. //设置分钟指针颜色
  98. void setPointerMinColor(const QColor &pointerMinColor);
  99. //设置秒钟指针颜色
  100. void setPointerSecColor(const QColor &pointerSecColor);
  101. };
  102. #endif // GAUGECLOCK_H

五、核心代码

  1. void GaugeClock::paintEvent(QPaintEvent *)
  2. {
  3. int width = this->width();
  4. int height = this->height();
  5. int side = qMin(width, height);
  6. //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
  7. QPainter painter(this);
  8. painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
  9. painter.translate(width / 2, height / 2);
  10. painter.scale(side / 200.0, side / 200.0);
  11. //绘制外边框
  12. drawCrown(&painter);
  13. //绘制背景
  14. drawBg(&painter);
  15. //绘制刻度线
  16. drawScale(&painter);
  17. //绘制刻度值
  18. drawScaleNum(&painter);
  19. //绘制时钟指针
  20. drawHour(&painter);
  21. //绘制分钟指针
  22. drawMin(&painter);
  23. //绘制秒钟指针
  24. drawSec(&painter);
  25. //绘制中心盖板
  26. drawDot(&painter);
  27. }
  28. void GaugeClock::drawCrown(QPainter *painter)
  29. {
  30. int radius = 99;
  31. painter->save();
  32. painter->setPen(Qt::NoPen);
  33. QLinearGradient crownGradient(0, -radius, 0, radius);
  34. crownGradient.setColorAt(0, crownColorStart);
  35. crownGradient.setColorAt(1, crownColorEnd);
  36. painter->setBrush(crownGradient);
  37. painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  38. painter->restore();
  39. }
  40. void GaugeClock::drawBg(QPainter *painter)
  41. {
  42. int radius = 92;
  43. painter->save();
  44. painter->setPen(Qt::NoPen);
  45. painter->setBrush(background);
  46. painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
  47. painter->restore();
  48. }
  49. void GaugeClock::drawScale(QPainter *painter)
  50. {
  51. int radius = 90;
  52. painter->save();
  53. QPen pen;
  54. pen.setColor(foreground);
  55. pen.setCapStyle(Qt::RoundCap);
  56. for (int i = 0; i <= 60; i++) {
  57. if (i % 5 == 0) {
  58. pen.setWidthF(1.5);
  59. painter->setPen(pen);
  60. painter->drawLine(0, radius - 10, 0, radius);
  61. } else {
  62. pen.setWidthF(0.5);
  63. painter->setPen(pen);
  64. painter->drawLine(0, radius - 5, 0, radius);
  65. }
  66. painter->rotate(6);
  67. }
  68. painter->restore();
  69. }
  70. void GaugeClock::drawScaleNum(QPainter *painter)
  71. {
  72. int radius = 70;
  73. painter->save();
  74. painter->setPen(foreground);
  75. double startRad = 60 * (M_PI / 180);
  76. double deltaRad = 30 * (M_PI / 180);
  77. for (int i = 0; i < 12; i++) {
  78. double sina = qSin(startRad - i * deltaRad);
  79. double cosa = qCos(startRad - i * deltaRad);
  80. QString strValue = QString("%1").arg(i + 1);
  81. double textWidth = fontMetrics().width(strValue);
  82. double textHeight = fontMetrics().height();
  83. int x = radius * cosa - textWidth / 2;
  84. int y = -radius * sina + textHeight / 4;
  85. painter->drawText(x, y, strValue);
  86. }
  87. painter->restore();
  88. }
  89. void GaugeClock::drawHour(QPainter *painter)
  90. {
  91. painter->save();
  92. //设置画笔平滑圆角
  93. QPen pen;
  94. pen.setCapStyle(Qt::RoundCap);
  95. painter->setPen(pointerHourColor);
  96. painter->setBrush(pointerHourColor);
  97. QPolygon pts;
  98. pts.setPoints(4, -3, 8, 3, 8, 2, -40, -2, -40);
  99. painter->rotate(30.0 * ((hour + min / 60.0)));
  100. painter->drawConvexPolygon(pts);
  101. painter->restore();
  102. }
  103. void GaugeClock::drawMin(QPainter *painter)
  104. {
  105. painter->save();
  106. //设置画笔平滑圆角
  107. QPen pen;
  108. pen.setCapStyle(Qt::RoundCap);
  109. painter->setPen(pointerMinColor);
  110. painter->setBrush(pointerMinColor);
  111. QPolygon pts;
  112. pts.setPoints(4, -2, 8, 2, 8, 1, -60, -1, -60);
  113. painter->rotate(6.0 * (min + sec / 60.0));
  114. painter->drawConvexPolygon(pts);
  115. painter->restore();
  116. }
  117. void GaugeClock::drawSec(QPainter *painter)
  118. {
  119. if (secondStyle == SecondStyle_Hide) {
  120. return;
  121. }
  122. painter->save();
  123. //设置画笔平滑圆角
  124. QPen pen;
  125. pen.setCapStyle(Qt::RoundCap);
  126. painter->setPen(pointerSecColor);
  127. painter->setBrush(pointerSecColor);
  128. QPolygon pts;
  129. pts.setPoints(3, -1, 10, 1, 10, 0, -70);
  130. painter->rotate(angleSpring);
  131. painter->drawConvexPolygon(pts);
  132. painter->restore();
  133. }
  134. void GaugeClock::drawDot(QPainter *painter)
  135. {
  136. painter->save();
  137. QConicalGradient coneGradient(0, 0, -90.0);
  138. coneGradient.setColorAt(0.0, background);
  139. coneGradient.setColorAt(0.5, foreground);
  140. coneGradient.setColorAt(1.0, background);
  141. painter->setOpacity(0.9);
  142. painter->setPen(Qt::NoPen);
  143. painter->setBrush(coneGradient);
  144. painter->drawEllipse(-5, -5, 10, 10);
  145. painter->restore();
  146. }
  147. void GaugeClock::doAction()
  148. {
  149. QAction *action = (QAction *)sender();
  150. QString str = action->text();
  151. if (str == "弹簧效果") {
  152. action->setText("连续效果");
  153. setSecondStyle(SecondStyle_Spring);
  154. } else if (str == "连续效果") {
  155. action->setText("隐藏效果");
  156. setSecondStyle(SecondStyle_Continue);
  157. } else if (str == "隐藏效果") {
  158. action->setText("普通效果");
  159. setSecondStyle(SecondStyle_Hide);
  160. } else if (str == "普通效果") {
  161. action->setText("弹簧效果");
  162. setSecondStyle(SecondStyle_Normal);
  163. }
  164. }

六、控件介绍

  1. 超过150个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,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. 目前已提供26个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
  17. 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
  18. Qt入门书籍推荐霍亚飞的《Qt Creator快速入门》《Qt5编程入门》,Qt进阶书籍推荐官方的《C++ GUI Qt4编程》。
  19. 强烈推荐程序员自我修养和规划系列书《大话程序员》《程序员的成长课》《解忧程序员》,受益匪浅,受益终生!
  20. SDK下载链接:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取码:877p

Qt编写自定义控件54-时钟仪表盘的更多相关文章

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

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

  2. Qt编写自定义控件4-旋转仪表盘

    前言 旋转仪表盘,一般用在需要触摸调节设置值的场景中,其实Qt本身就提供了QDial控件具有类似的功能,本控件最大的难点不在于绘制刻度和指针等,而在于自动计算当前用户按下处的坐标转换为当前值,这个功能 ...

  3. Qt编写自定义控件3-速度仪表盘

    前言 速度仪表盘,写作之初的本意是用来展示当前测试的网速用的,三色圆环+数码管显示当前速度,Qt自带了数码管控件QLCDNumber,直接集成即可,同时还带有动画功能,其实也可以用在汽车+工业领域等, ...

  4. Qt编写自定义控件1-汽车仪表盘

    前言 汽车仪表盘几乎是qt写仪表盘控件中最常见的,一般来说先要求美工做好设计图,然后设计效果图给到程序员,由程序员根据效果来实现,主要靠贴图,这种方法有个好处就是做出来的效果比较逼真,和真实效果图基本 ...

  5. Qt编写自定义控件12-进度仪表盘

    前言 进度仪表盘主要应用场景是标识一个任务进度完成的状况等,可以自由的设置范围值和当前值,为了美观还提供了四种指示器(圆形指示器/指针指示器/圆角指针指示器/三角形指示器),各种颜色都可以设置,其中的 ...

  6. Qt编写自定义控件51-可输入仪表盘

    一.前言 这个控件是近期定制的控件,还是比较实用的控件之一,用户主要是提了三点需求,一点是切换焦点的时候控件放大突出显示,一点是可直接输入或者编辑值,还有一点是支持上下键及翻页键和鼠标滚轮来动态修改值 ...

  7. Qt编写自定义控件50-迷你仪表盘

    一.前言 这个控件取名叫迷你仪表盘,是以为该控件可以缩小到很小很小的区域显示,非常适合小面积区域展示仪表数据使用,还可以手动触摸调节进度,是我个人觉得最漂亮小巧的一个控件.初次看到类似的控件是在一个音 ...

  8. Qt编写自定义控件49-飞机仪表盘

    一.前言 飞行仪表是测定和表示飞机数据的工具,飞机中必不可少的一部分,飞行员根据飞行仪表表示的数据才能正确地做出判断.一般飞机仪表包括高度表+空速表+垂直速率表+姿态仪+航向指示表+转弯协调表. 这次 ...

  9. Qt编写自定义控件44-天气仪表盘

    一.前言 天气仪表盘控件是所有控件中唯一一个使用了svg矢量图的控件,各种天气图标采用的矢量图,颜色变换采用动态载入svg的内容更改生成的,其实也可以采用图形字体来做,本次控件为了熟悉下svg在Qt中 ...

随机推荐

  1. G1垃圾收集器堆内存划分与角色分派【纯理论】

    接着上一次[https://www.cnblogs.com/webor2006/p/11123522.html]G1学习继续开启理论之旅.. G1的设计规划是要替换掉CMS[理想化的] G1在某些方面 ...

  2. linux网络编程之posix信号量与互斥锁

    继上次学习了posix线程之后,这次来讨论一下posix信号量与互斥锁相关的知识: 跟posix消息队列,共享内存的打开,关闭,删除操作一样,不过,上面的函数是对有名信号量进行操作,通过man帮助可以 ...

  3. Spring Security 流程

    首先创建4个类 流程大致如下: 1.容器启动 加载系统资源与权限列表(HashMap) MyInvocationSecurityMetadataSourceService中的loadResourceD ...

  4. 判断变量是否不为空,函数isset()、!empty()与!is_null()的比较

    转载:https://blog.csdn.net/qq_38812954/article/details/79581785 判断变量的值,尤其是判断他们是否不为空,我们有以下4种方法: if(isse ...

  5. / WebAPP开发与小程序 / 步骤一 · 4-5 地图搜索与poi结合(2)

    / WebAPP开发与小程序 / 步骤一 · 4-5 地图搜索与poi结合(2) 在地图中搜索指定对象时,搜索结果可以显示出每个对象的图片,就差这个不会了

  6. java+下载+大文件断点续传

    java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路:1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接操 ...

  7. vue+大文件上传控件

    总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...

  8. learning scala regular expression patterns

    package com.aura.scala.day01 import scala.util.matching.Regex object regularExpressionPatterns { def ...

  9. 运行级别 runlevel

    linux默认有7个等级,从0到6 0 关机 1 单用户模式,系统出现问题是可使用该模式进入系统.例如完了root密码,就可以使用1进入系统修改root密码 2 多用户模式,没有网络连接 3 完全多用 ...

  10. C#中指针的简单使用

    原来C#不仅仅支持和C/C++中指针(或者说是引用)很像的委托delegate,还支持在unsafe代码块中使用指针,从而写非托管的代码(人为不让垃圾回收机制来管理相应的内存).在unsafe中就可以 ...