由于上位机需要绘制电压电阻表盘,如下图所示:

后来,在网上找阿找,还是没找到满意的,索性自己来画控件算了,由于第一次画控件,所以花了我2天时间,才画好

效果图如下:

上图的所有颜色(包括滑动的渐变/单一颜色,以及字体颜色)都可以自定义,包括图标也可以(上面的电阻图标,网上没找到好看的,所以很丑~)

整体效果图如下所示:

该demo程序放在了提供的源码地址里了,下载好后,在子文件夹demo1里面

介绍

代码里添加了自适应设置,根据窗口大小自动改变标签,图标,刻度值,中心圆数值等

代码里集成了定时器,可以通过setTimerType(int msec,int v)成员函数实现表盘指针旋转快慢,每过多少msec,跑多少值(v),如果msec=0或者v=0,则表示不用定时器,直接跳到终点。

代码里通过setGradientColorMode(QList<QColor>& Qcolors)成员函数可以自定义一组渐变颜色.

也可以通过setSingleColorMode(QColor color)成员函数自定义单一颜色(上图2就是设置的单一颜色).

代码介绍

1.代码里通过 painter类来绘图,其中paintEvent()函数如下所示

  1. void Dial::paintEvent(QPaintEvent *)
  2. {
  3. QPainter painter(this);
  4. painter.setPen(Qt::NoPen);
  5. painter.setRenderHint(QPainter::Antialiasing,true);
  6. painter.setRenderHint(QPainter::SmoothPixmapTransform);
  7. painter.translate(width()/,height()/);
  8. radius = qMin(width(),height())/;
  9. centerR=radius*0.4; //设置中心圆大小
  10. drawObkColor(painter); //外圆盘
  11. drawScalebkColor(painter); //画刻度圆
  12. drawslideScaleColor(painter); //画划过的颜色
  13. drawShade(painter); //画阴影
  14. drawScaleColor(painter);
  15. drawbkColor(painter); //画内圆
  16. drawScaleTextColor(painter); //画刻度值
  17. drawPointColor(painter);
  18. drawCenterColor(painter); //绘制中心圆
  19. drawIconValueColor(painter);
  20. drawlabelColor(painter);
  21. }

2.然后进入drawObkColor()函数,来绘画外圆盘,函数如下所示

  1. void Dial::drawObkColor(QPainter& paint) //绘制外圆
  2. {
  3. paint.save();
  4. QConicalGradient Conical(,,);
  5. Conical.setColorAt(,oobkColor);
  6. Conical.setColorAt(0.5,oobkColor);
  7. Conical.setColorAt(0.12,oobkColor.darker());
  8. Conical.setColorAt(0.88,oobkColor.darker());
  9. Conical.setColorAt(0.4,oobkColor.darker());
  10. Conical.setColorAt(0.6,oobkColor.darker());
  11. Conical.setColorAt(0.25,oobkColor.darker());
  12. Conical.setColorAt(0.75,oobkColor.darker());
  13. Conical.setColorAt(,oobkColor);
  14. paint.setBrush(Conical);
  15. paint.drawEllipse(QPointF(,), radius*0.96,radius*0.98);
  16. Conical.setAngle();
  17. Conical.setColorAt(,obkColor.darker());
  18. Conical.setColorAt(0.5,obkColor.darker());
  19. Conical.setColorAt(0.25,obkColor.darker());
  20. Conical.setColorAt(0.75,obkColor.darker());
  21. paint.setBrush(Conical);
  22. paint.drawEllipse(QPointF(,), radius*0.93,radius*0.94);
  23. paint.restore();
  24. }

外圆盘效果如下所示:

3.然后接下来开始画刻度圆,画了它后,才能开始画刻度和划过的颜色等

  1. void Dial::drawScalebkColor(QPainter &paint) //绘制刻度圆
  2. {
  3. paint.save();
  4. paint.setBrush(bkColor);
  5. paint.drawEllipse(QPointF(,), radius*0.90,radius*0.90);
  6.  
  7. paint.restore();
  8. }

4.然后接下来开始画划过的颜色,就是上图指针划过后都会带有颜色的那种 (以单色颜色为例)

  1. void Dial::drawslideScaleColor(QPainter &paint) //画划过的颜色
  2. {
  3. /*单一颜色*/
  4.  
  5. int Star_Angle= *-(int)((value/(maxvalue-minvalue))**);
  6.  
  7. int spanAngle = * - Star_Angle;
  8.  
  9. if(spanAngle==)
  10. return ;
  11.  
  12. qreal SlideBottom = ((qreal)radius*0.77)/((qreal)radius*0.90);
  13.  
  14. qreal SlideCenterTop = -(-SlideBottom)/;
  15. qreal SlideCenterBottom = SlideBottom+(-SlideBottom)/+0.01;
  16.  
  17. paint.save();
  18.  
  19. QColor Tint_SlideColor = SingleSlideColor;
  20.  
  21. QRadialGradient Radial(,,radius*0.90);
  22.  
  23. Tint_SlideColor.setAlpha();
  24. Radial.setColorAt(,Tint_SlideColor);
  25. Radial.setColorAt(SlideBottom-0.005,Tint_SlideColor);
  26. Radial.setColorAt(,Qt::transparent);
  27. Radial.setColorAt(SlideBottom-0.006,Qt::transparent);
  28.  
  29. Tint_SlideColor = SingleSlideColor;
  30. Tint_SlideColor.setAlpha();
  31.  
  32. Radial.setColorAt(SlideCenterBottom-0.03,Tint_SlideColor);
  33. Radial.setColorAt(SlideCenterTop+0.03,Tint_SlideColor);
  34.  
  35. Tint_SlideColor = SingleSlideColor;
  36. Tint_SlideColor.setAlpha();
  37. Radial.setColorAt(SlideCenterBottom-0.01,SingleSlideColor.darker());
  38. Radial.setColorAt(SlideCenterTop+0.01,SingleSlideColor.darker());
  39.  
  40. Radial.setColorAt(SlideCenterBottom,SingleSlideColor);
  41. Radial.setColorAt(SlideCenterTop,SingleSlideColor);
  42.  
  43. paint.setPen(Qt::NoPen);
  44. paint.setBrush(Radial);
  45.  
  46. paint.drawPie(QRectF((qreal)-radius*0.90,(qreal)-radius*0.90,(qreal)radius*1.80,(qreal)radius*1.80),Star_Angle,spanAngle);
  47.  
  48. paint.restore();
  49.  
  50. //... ...
  51.  
  52. }

效果:

5.然后接下来便开始画刻度和刻度值,其中比较重要的就是绘制刻度值

由于Painter的rotate()旋转文字时,也会将文字倾斜了,所以我们需要自定义rotate()函数

具体参考我另一篇rotate函数分析:    31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待

drawScaleTextColor()画刻度值函数如下所示:

  1. void Dial::drawScaleTextColor(QPainter &paint) //绘制刻度值
  2. {
  3. /*绘制文字刻度*/
  4. paint.save();
  5.  
  6. paint.setPen(ScaleColor);
  7.  
  8. QString text("%1");
  9.  
  10. int size; //动态计算文字大小
  11.  
  12. if(radius<=)
  13. size = ;
  14. else if((radius>)&&(radius<))
  15. size = +(radius-)/;
  16. else if(radius>=)
  17. size = +(radius-)/;
  18.  
  19. paint.setFont(QFont("Euphemia",size,QFont::DemiBold));
  20.  
  21. QPoint TextPoint(,radius*0.77-size*0.9); //设置90°的文字
  22. TextPoint = CustomRotate(TextPoint,,); //获取点=210°的文字位置
  23. qreal TextRotate=;
  24.  
  25. for(int i=;i<;i++) //设置7个刻度值
  26. {
  27.  
  28. //... ...
  29.  
  30. qreal Current_Value =(qreal)i*((maxvalue-minvalue)/);
  31.  
  32. if((Current_Value>value&&(paint.pen().color()!=ScaleColor)))
  33. {
  34. paint.setPen(ScaleColor);
  35.  
  36. }
  37. else if((Current_Value<=value&&(paint.pen().color()!=slideScaleColor)))
  38. {
  39. paint.setPen(slideScaleColor);
  40. }
  41.  
  42. paint.drawText(QRect(TextPoint.x()-size*1.5+offest[i].x(),TextPoint.y()-size*1.2+offest[i].y(),size*,size*2.4),alingns[i],text.arg((maxvalue-minvalue)*i/));
  43. TextPoint = CustomRotate(TextPoint,TextRotate,); //获取点=210°的文字位置
  44. TextRotate-=;
  45. }
  46.  
  47. paint.restore();
  48. }

效果如下所示:

6.然后接下来开始画指针

  1. void Dial::drawPointColor(QPainter &paint) //绘制指针
  2. {
  3.  
  4. qreal PointTop; //动态计算指针头
  5. qreal PointBottom; //动态计算指针底部
  6. if(radius<=)
  7. {
  8. PointTop = ;
  9. PointBottom = ;
  10. }
  11. else if((radius>)&&(radius<))
  12. {
  13. PointTop = + (radius-)/;
  14. PointBottom = PointTop*;
  15. }
  16. else if(radius>=)
  17. {
  18. PointTop = + (radius-)/;
  19. PointBottom = PointTop*;
  20. }
  21.  
  22. //指针
  23. const QPointF Pointer[] = {
  24. QPointF(- PointTop / , radius*0.80),
  25. QPointF(PointTop / , radius*0.80),
  26. QPointF(PointBottom / , centerR*0.9),
  27. QPointF(-PointBottom / , centerR*0.9)
  28. };
  29.  
  30. paint.save();
  31.  
  32. paint.setBrush(PointerColor);
  33. paint.setPen(PointerColor.darker());
  34.  
  35. qreal Current_Angle =+(int)((value/(maxvalue-minvalue))*);
  36.  
  37. paint.rotate(Current_Angle);
  38.  
  39. paint.drawConvexPolygon(Pointer, );
  40.  
  41. paint.restore();
  42.  
  43. }

效果如下:

7.然后继续画中心圆

  1. void Dial::drawCenterColor(QPainter &paint) //绘制中心圆
  2. {
  3. paint.save();
  4.  
  5. QRadialGradient Radial(,,centerR,,);
  6.  
  7. Radial.setColorAt(,centercolor.lighter());
  8. Radial.setColorAt(0.98,centercolor.lighter());
  9. Radial.setColorAt(0.95,centercolor.lighter());
  10. Radial.setColorAt(0.70,centercolor);
  11.  
  12. paint.setBrush(Radial);
  13. paint.drawEllipse(QPointF(,), centerR,centerR);
  14.  
  15. paint.restore();
  16.  
  17. }

效果如下:

剩下的代码就是画标签和值还有图标啦,由于渐变代码多一些,所以具体参考可以去下载源代码.在最下面有下载地址


2018-06-30    第二次更新

内容

  • 支持负数到正数刻度值显示
  • 支持小数点位数设置
  • 优化刻度值自适应窗口,能具体显示个位至千位
  • 支持表盘所有颜色搭配
  • 添加arriveEnd()信号函数

并写了个demo测试程序,可以直接测试数据,demo程序效果图如下所示:

该demo程序放在了提供的源码地址里了,下载好后,在文件夹demo2里面

 测试图1-设置颜色(任意搭配颜色):

测试图2-设置正负数值:

 


2018-07-01    第三次更新

  • 在上个更新里,添加了表盘阴影效果,来实现立体感

如下图的第二个表盘所示:

该demo程序放在了提供的源码地址里了,下载好后,在文件夹demo3里面

主要内容:

  添加了一个drawDialShade(QPainter &paint,qreal Angle_start,qreal Angle_end,qreal ratio,int alpha)成员函数,来绘制白色阴影,实现的光影效果.

该函数的参数含义如下所示:

  • Angle_start Angle_end :表示圆盘的起始/结束角度,Angle_end必须大于Angle_start哦
  • ratio:表示绘制的阴影亮度的扁与平(为0~1之间),为0表示平的圆环,为0.99表示最扁的圆环,大于等于1则不会绘制
  • alpha:表示铺上的白色透明度,0表示透明,255表示不透明

如果觉得上图的阴影效果觉得不合适,可以自己修改哦~

drawDialShade()函数使用示例:

1.单独调用drawDialShade(painter,30,180,0,255)时

含义:  表示在内圆盘上的30°~180°之间绘制圆月,ratio=0,所以圆月是平的,alpha=255,表示不透明

效果如下:

2.单独调用drawDialShade(painter,45,180,0.5,150)时

含义:  表示在内圆盘上的45°~180°之间绘制圆月,圆月是半扁的,半透明

效果如下:

PS:要实现更强的立体感,多次调用改参数即可

上面所有源码已放在源代码下载地址里了,具体源代码下载地址为:

https://download.csdn.net/download/qq_37997682/10512710


2019-05-29 (QT5版本更新)

  • 由于之前上传的表盘是QT4版本 编码为GBK的,对有些只学过QT5的同学们不好移植,所以从新上传一个QT5版本的,编码格式为utf-8

如下图所示:

下载地址为:   https://download.csdn.net/download/qq_37997682/11214644

如果觉得不错,点个赞呗~

32.QT-制作最强电压电阻表盘,可以自定义阴影效果,渐变颜色,图标,文字标签等-附带demo程序的更多相关文章

  1. Linux输入子系统 转载

    NQian 记录成长~ 首页 新随笔 联系 订阅 管理 随笔 - 305  文章 - 0  评论 - 254 12.Linux之输入子系统分析(详解)   在此节之前,我们学的都是简单的字符驱动,涉及 ...

  2. Qt 制作安装包

    Qt 制作在线.离线 安装包 见如下文档

  3. Qt制作Aero特效窗口

    转载请注明链接与作者huihui1988 初学QT,边看书边自己做点小东西.最近突然心血来潮,想自己做个小巧点的,界面美观一点的备忘当桌面上.想了半天,发现VISTA/WIN7的Aero效果就不错,况 ...

  4. 使用qt制作一个简单的计算器

    前言:今天使用qt制作了一个很简单的计算器,觉得挺有意思的,所以在这里跟大家分享一下. 这里先跟大家说说使用到的函数: 一.槽连接函数 connect(信号发送者,发送的信号,信号接收者,信号接收者的 ...

  5. QT制作一个图片播放器

    前言:使用qt制作了一个简单的图片播放器,可以播放gif.png等格式图片 先来看看播放器的功能(当然是很简陋的,没有很深入的设计): 1.点击图片列表中图片进行播放. 2.自动播放,播放的图片的间隔 ...

  6. 个人永久性免费-Excel催化剂功能第77波-专业图表制作辅助之批量维护序列点颜色及数据标签

    2018年最后一天工作日完成第77波,7是代表完美,2个7,双重的完美,Excel催化剂的2018年从始至终共77波都充满着完美接近极致的功能体验.感谢各位一路相随,陪伴成长.最后一波,再次让数据分析 ...

  7. 用Html5结合Qt制作一款本地化EXE游戏-太空大战(Space War)

    本次来说一说如何利用lufylegend.js引擎制作一款html5游戏后将其通过Qt转换成EXE程序.步骤其实非常简单,接下来就一步步地做一下解释和说明. 首先我们来开发一个有点类似于太空大战的游戏 ...

  8. 用Qt制作的Android独立游戏《吃药了》公布

           一个多月的努力最终有了回报,我自己研究制作的独立游戏<吃药了>.最终在360应用商店上线了.        这一款游戏呢.使用的是Qt开发的.事实上开发这款简单的应用之前.我 ...

  9. QT 制作串口调试小助手----(小白篇)

    一.成品图展示 简介:因zigbee实验,制作一个相对简易版的上位机,接收来自zigbee无线传感采集的温湿度.光照等数据. 并且将数据部分描绘成实时动态折线统计图. 二.主要功能介绍 主要使用QT自 ...

随机推荐

  1. jquery跨域方法

    $.ajax({ type: 'get', dataType: "jsonp",//支持跨域 jsonp: "callback", jsonpCallback: ...

  2. C++ 引用、构造函数、移动语义

    1.引用 C++中的引用主要用作函数的形参,接近于const指针,必须在创建时初始化. 以Person类为例,如下: Person p;                          //调用P的 ...

  3. 1-C++的并发世界

    1.1 何谓并发 并发的两种方式 多核机器上的真正并行 单核机器的任务切换 并发的两种途径 多进程并发 1.1 多进程并发需要通过操作系统进行进程间通信 多线程并发 2.1 多线程并发需要共享内存 1 ...

  4. Java中最常用的集合类框架之 HashMap

    一.HashMap的概述 HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构.      HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射 ...

  5. Javascript高级编程学习笔记(82)—— 富文本操作(2)

    操作富文本 与富文本编辑器的交互的主要方式就是使用 document.execCommand() 方法 该方法可以对文档执行自定义命令,并且可以应用大多数格式 该方法接收三个参数: 要执行命令的名称 ...

  6. HttpServlet的转发和重定向

    HttpServletResponse重定向 1.HTTP协议规定了一种重定向的机制,重定向的运作流程如下 用户在浏览器输入特定的URL,请求访问服务端的某个组件. 服务端的组件返回一个状态码为302 ...

  7. Python super() 函数的概念和例子

    概念: super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重 ...

  8. ubuntu 16.04 安装cuda的方法

    很多神经网络架构都需要安装CUDA,安装这个的确费了我不少时间,是要总结一下流程了. 安装这个,最好使用官网的安装步骤和流程,不然,会走很多弯路: https://developer.nvidia.c ...

  9. new 操作符 做了什么

    new 操作符 做了什么 new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例. 假设Test是一个构造函数,通常在创建对象的实例时,要使用new,eg:test = new ...

  10. java开发个人简历

    求职意向 Java开发工程师 陈 楠 性 别:男 出生年月 :1995.07 民 族:汉族 联系方式 :159-3306-7520 学 历:本科 电子邮件 :15933067520@163.com 教 ...