首先声明,这是转载的,不过作者做的很漂亮,使得我无法拒绝给他转载。
效果:
原文:https://www.cnblogs.com/lifexy/p/9245918.html
原文比较啰嗦,我就简单摘录:
代码介绍
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.然后接下来便开始画刻度和刻度值,其中比较重要的就是绘制刻度值
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();
}
剩下的代码就是画标签和值还有图标啦,由于渐变代码多一些,所以具体参考可以去下载源代码.下载地址:
https://download.youkuaiyun.com/download/qq_37997682/11214644
原文章pdf下载:http://labisart.com/blog/index.php/Home/Index/article/aid/202