32.QT-制作最强电压电阻表盘,可以自定义颜色,图…
2018-07-03 01:01:14来源:博客园 阅读 ()
由于上位机需要绘制电压电阻表盘,如下图所示:
后来,在网上找阿找,还是没找到满意的,索性自己来画控件算了,由于第一次画控件,所以花了我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()函数如下所示
void Dial::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setPen(Qt::NoPen); painter.setRenderHint(QPainter::Antialiasing,true); painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.translate(width()/2,height()/2); radius = qMin(width(),height())/2; centerR=radius*0.4; //设置中心圆大小 drawObkColor(painter); //外圆盘 drawScalebkColor(painter); //画刻度圆 drawslideScaleColor(painter); //画划过的颜色 drawShade(painter); //画阴影 drawScaleColor(painter); drawbkColor(painter); //画内圆 drawScaleTextColor(painter); //画刻度值 drawPointColor(painter); drawCenterColor(painter); //绘制中心圆 drawIconValueColor(painter); drawlabelColor(painter); }
2.然后进入drawObkColor()函数,来绘画外圆盘,函数如下所示
void Dial::drawObkColor(QPainter& paint) //绘制外圆 { paint.save(); QConicalGradient Conical(0,0,90); Conical.setColorAt(0,oobkColor); Conical.setColorAt(0.5,oobkColor); Conical.setColorAt(0.12,oobkColor.darker(40)); Conical.setColorAt(0.88,oobkColor.darker(40)); Conical.setColorAt(0.4,oobkColor.darker(30)); Conical.setColorAt(0.6,oobkColor.darker(30)); Conical.setColorAt(0.25,oobkColor.darker(160)); Conical.setColorAt(0.75,oobkColor.darker(160)); Conical.setColorAt(1,oobkColor); paint.setBrush(Conical); paint.drawEllipse(QPointF(0,0), radius*0.96,radius*0.98); Conical.setAngle(270); Conical.setColorAt(0,obkColor.darker(40)); Conical.setColorAt(0.5,obkColor.darker(40)); Conical.setColorAt(0.25,obkColor.darker(160)); Conical.setColorAt(0.75,obkColor.darker(160)); paint.setBrush(Conical); paint.drawEllipse(QPointF(0,0), radius*0.93,radius*0.94); paint.restore(); }
外圆盘效果如下所示:
3.然后接下来开始画刻度圆,画了它后,才能开始画刻度和划过的颜色等
void Dial::drawScalebkColor(QPainter &paint) //绘制刻度圆 { paint.save(); paint.setBrush(bkColor); paint.drawEllipse(QPointF(0,0), radius*0.90,radius*0.90); paint.restore(); }
4.然后接下来开始画划过的颜色,就是上图指针划过后都会带有颜色的那种 (以单色颜色为例)
void Dial::drawslideScaleColor(QPainter &paint) //画划过的颜色 { /*单一颜色*/ int Star_Angle= 210*16-(int)((value/(maxvalue-minvalue))*240*16); int spanAngle = 210*16 - Star_Angle; if(spanAngle==0) return ; qreal SlideBottom = ((qreal)radius*0.77)/((qreal)radius*0.90); qreal SlideCenterTop = 1-(1-SlideBottom)/3; qreal SlideCenterBottom = SlideBottom+(1-SlideBottom)/3+0.01; paint.save(); QColor Tint_SlideColor = SingleSlideColor; QRadialGradient Radial(0,0,radius*0.90); Tint_SlideColor.setAlpha(40); Radial.setColorAt(1,Tint_SlideColor); Radial.setColorAt(SlideBottom-0.005,Tint_SlideColor); Radial.setColorAt(0,Qt::transparent); Radial.setColorAt(SlideBottom-0.006,Qt::transparent); Tint_SlideColor = SingleSlideColor; Tint_SlideColor.setAlpha(50); Radial.setColorAt(SlideCenterBottom-0.03,Tint_SlideColor); Radial.setColorAt(SlideCenterTop+0.03,Tint_SlideColor); Tint_SlideColor = SingleSlideColor; Tint_SlideColor.setAlpha(50); Radial.setColorAt(SlideCenterBottom-0.01,SingleSlideColor.darker(200)); Radial.setColorAt(SlideCenterTop+0.01,SingleSlideColor.darker(200)); Radial.setColorAt(SlideCenterBottom,SingleSlideColor); Radial.setColorAt(SlideCenterTop,SingleSlideColor); paint.setPen(Qt::NoPen); paint.setBrush(Radial); paint.drawPie(QRectF((qreal)-radius*0.90,(qreal)-radius*0.90,(qreal)radius*1.80,(qreal)radius*1.80),Star_Angle,spanAngle); paint.restore(); //... ... }
效果:
5.然后接下来便开始画刻度和刻度值,其中比较重要的就是绘制刻度值
由于Painter的rotate()旋转文字时,也会将文字倾斜了,所以我们需要自定义rotate()函数
具体参考我另一篇rotate函数分析: 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待
drawScaleTextColor()画刻度值函数如下所示:
void Dial::drawScaleTextColor(QPainter &paint) //绘制刻度值 { /*绘制文字刻度*/ paint.save(); paint.setPen(ScaleColor); QString text("%1"); int size; //动态计算文字大小 if(radius<=120) size = 10; else if((radius>120)&&(radius<500)) size = 13+(radius-120)/30; else if(radius>=500) size = 13+(radius-120)/40; paint.setFont(QFont("Euphemia",size,QFont::DemiBold)); QPoint TextPoint(0,radius*0.77-size*0.9); //设置90°的文字 TextPoint = CustomRotate(TextPoint,90,240); //获取点=210°的文字位置 qreal TextRotate=210; for(int i=0;i<7;i++) //设置7个刻度值 { //... ... qreal Current_Value =(qreal)i*((maxvalue-minvalue)/6); if((Current_Value>value&&(paint.pen().color()!=ScaleColor))) { paint.setPen(ScaleColor); } else if((Current_Value<=value&&(paint.pen().color()!=slideScaleColor))) { paint.setPen(slideScaleColor); } paint.drawText(QRect(TextPoint.x()-size*1.5+offest[i].x(),TextPoint.y()-size*1.2+offest[i].y(),size*3,size*2.4),alingns[i],text.arg((maxvalue-minvalue)*i/6)); TextPoint = CustomRotate(TextPoint,TextRotate,40); //获取点=210°的文字位置 TextRotate-=40; } paint.restore(); }
效果如下所示:
6.然后接下来开始画指针
void Dial::drawPointColor(QPainter &paint) //绘制指针 { qreal PointTop; //动态计算指针头 qreal PointBottom; //动态计算指针底部 if(radius<=120) { PointTop = 2; PointBottom = 6; } else if((radius>120)&&(radius<500)) { PointTop = 2 + (radius-120)/100; PointBottom = PointTop*3; } else if(radius>=500) { PointTop = 2 + (radius-120)/140; PointBottom = PointTop*3; } //指针 const QPointF Pointer[4] = { QPointF(- PointTop / 2, radius*0.80), QPointF(PointTop / 2, radius*0.80), QPointF(PointBottom / 2, centerR*0.9), QPointF(-PointBottom / 2, centerR*0.9) }; paint.save(); paint.setBrush(PointerColor); paint.setPen(PointerColor.darker(300)); qreal Current_Angle =60+(int)((value/(maxvalue-minvalue))*240); paint.rotate(Current_Angle); paint.drawConvexPolygon(Pointer, 4); paint.restore(); }
效果如下:
7.然后继续画中心圆
void Dial::drawCenterColor(QPainter &paint) //绘制中心圆 { paint.save(); QRadialGradient Radial(0,0,centerR,0,0); Radial.setColorAt(1,centercolor.lighter(170)); Radial.setColorAt(0.98,centercolor.lighter(150)); Radial.setColorAt(0.95,centercolor.lighter(130)); Radial.setColorAt(0.70,centercolor); paint.setBrush(Radial); paint.drawEllipse(QPointF(0,0), centerR,centerR); paint.restore(); }
效果如下:
剩下的代码就是画标签和值还有图标啦,由于渐变代码多一些,所以具体参考可以去下载源代码.在最下面有下载地址
2018-07-01 第二次更新
内容
- 支持负数到正数刻度值显示
- 支持小数点位数设置
- 优化刻度值自适应窗口,能具体显示个位至千位
- 支持表盘所有颜色搭配
- 添加arriveEnd()信号函数
并写了个demo测试程序,可以直接测试数据,demo程序效果图如下所示:
该demo程序放在了提供的源码地址里了,下载好后,在文件夹demo2里面
测试图1-设置颜色(任意搭配颜色):
测试图2-设置正负数值:
demo测试程序已放在源代码下载地址里了,具体源代码下载地址为:
https://download.csdn.net/download/qq_37997682/10509237
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 用QT制作3D点云显示器——QtDataVisualization 2020-05-07
- UOJ192 最强跳蚤 2020-02-05
- 34.QT-制作串口助手(并动态检测在线串口,附带源码) 2018-07-09
- 20个最强的基于浏览器的在线代码编辑器 2018-06-27
- 用Arduino制作一个二维码显示器 2018-06-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash