源码
圆弧上的点,对应的坐标计算方式。
x1 = x0 + r * cos(angle * 3.14 /180 )
y1 = y0 + r * sin(angle * 3.14 /180 )
x0 y0 —>中心点 angle 角度
qwidget(paintevent事件实现)废话不多说实现逻辑如下:
void UMeter::paintEvent(QPaintEvent *event)
{
int radius = 100;
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.translate(width() / 2, height() / 2);
#if 1
int anglevalue = 0;
QPen pen;
pen.setColor(QColor("#646464A0"));
pen.setWidth(4);
p.setPen(pen);
p.drawEllipse(QPoint(0,0),radius+4,radius+4);
p.setPen(QColor("#636363"));
p.drawEllipse(QPoint(0,0),radius+5,radius+5);
p.setPen(QColor("#636363"));
p.setBrush(Qt::black);
p.drawEllipse(QPoint(0,0),radius,radius);
p.setPen(QColor("#636363"));
setLinearGradientColor(p,QColor("#FF005600"),QColor("#FF005600"),QColor("#00005600"),QPointF(0,-radius),QPointF(0,radius));
p.drawEllipse(QPoint(0,0),radius,radius);
p.setPen(Qt::red);
for (int i = 0; i < BigScale; ++i) {
if (anglevalue < 60 || anglevalue > 120)
{
p.drawLine(85,0,radius,0);
}
double angle = 360.00/BigScale;
p.rotate(angle);
anglevalue = anglevalue + angle;
}
anglevalue = 0;
p.setPen(Qt::yellow);
for (int i = 0; i < ModleScale; ++i) {
if (anglevalue <= 60 || anglevalue >= 120)
{
if (i % 3 != 0)
p.drawLine(90,0,radius,0);
}
double angle = 360.00/ModleScale;
p.rotate(angle);
anglevalue = anglevalue + angle;
}
anglevalue = 0;
p.setPen(Qt::white);
for (int i = 0; i < SmallScale; ++i) {
if (anglevalue < 60 || anglevalue > 120)
{
if (i % 5 != 0)
p.drawLine(95,0,radius,0);
}
double angle = 360.00/SmallScale;
p.rotate(angle);
anglevalue = anglevalue + angle;
}
anglevalue = 0;
p.setPen(Qt::white);
QStringList list;
list<<"180"<<"210"<<"240"<<"270"<<"300"<<"330"<<"360"<<"30"<<"60"<<"90"<<"120"<<"150";
for (int i = 0; i < ModleScale; ++i) {
if (anglevalue >= 210 || anglevalue <= 150)
{
p.drawText(QRect(-8,-85,16,16),Qt::AlignHCenter,list[i]);
}
double angle = 360.00/ModleScale;
p.rotate(angle);
anglevalue = anglevalue + angle;
}
p.save();
pen.setColor(Qt::gray);
p.setPen(pen);
QPoint points[3];
points[0] = QPoint(-3,0);
points[1] = QPoint(3,0);
points[2] = QPoint(0,radius);
if (m_xangle < 30)
m_xangle = 330;
else if(m_xangle>330)
m_xangle = 30;
p.rotate(m_xangle);
p.drawConvexPolygon(points,3);
p.restore();
QString val = QString("%1km/h").arg(m_xangle);
pen.setColor(Qt::white);
p.setPen(pen);
p.setFont(QFont("微软雅黑",12,QFont::Bold,false));
p.drawText(-50,40,radius,40,Qt::AlignHCenter,val);
//圆弧
setConicalGradientColor(p,QColor("#FFFF0000"),QColor("#7DFF0000"),QColor("#FF005600"),QColor("#007D5600"),QPoint(0,0),245);
QRect arcRect = QRect(-radius-10,-radius-10,2*(radius+10),2*(radius+10));
double startAngle = 240 * 16;
double spanAngle = -(m_xangle - 30) * 16;
p.drawArc(arcRect,startAngle,spanAngle);
//文字底盘
p.setBrush(Qt::NoBrush);
pen.setColor("#3074c6");
pen.setWidth(20);
p.setPen(pen);
p.drawEllipse(QPoint(0,0),radius+30,radius+30);
p.setBrush(Qt::NoBrush);
p.setPen(Qt::black);
p.drawEllipse(QPoint(0,0),radius+20,radius+20);
p.drawEllipse(QPoint(0,0),radius+40,radius+40);
#endif
//跑马灯圆弧
QConicalGradient conicalGradient(QPoint(0,0),-m_xangle);
conicalGradient.setColorAt(0,QColor("#81aff3"));
conicalGradient.setColorAt(0.60,QColor("#FFFFFF"));
conicalGradient.setColorAt(0.63,QColor("#FFFFFF"));
conicalGradient.setColorAt(1,QColor("#81aff3"));
conicalGradient.setSpread(QGradient::PadSpread);
pen = QPen(QBrush(conicalGradient),5);
p.setPen(pen);
QRect lightarcRect = QRect(-radius-30,-radius-30,2*(radius+30),2*(radius+30));
startAngle = (240-m_xangle+45) * 16;
spanAngle = -30 * 16;
p.drawArc(lightarcRect,startAngle,spanAngle);
//文字
p.setPen(Qt::black);
int font_size = 16;
// 设置字符间距
QFont font;
font.setFamily("Microsoft YaHei");
// 大小
font.setPointSize(font_size);
// 使用字体
p.setFont(font);
//圆弧上的点,对应的坐标计算方式。
//x1 = x0 + r * cos(angle * 3.14 /180 )
//y1 = y0 + r * sin(angle * 3.14 /180 )
//x0 y0 —>中心点 angle 角度
#if 0
static QString m_string("12345678");
for(int i=0; i<m_string.count(); i++)
{
// 按正弦函数绘制
int ang = -180/(m_string.count()-1)*i;
float tx = -7.5-(radius+30)*cos(ang*(3.14/180));
float ty = (radius+20)*sin(ang*(3.14/180));
// qDebug()<<tx<<ang<<ty;
//压缩y坐标
p.drawText(QPointF(tx, ty), QString("%1").arg(m_string[i]));
}
#else
QString str1("正常模式");
p.setPen(Qt::green);
for(int i=0; i<str1.count(); i++)
{
// 按正弦函数绘制
int bAngle = 60;
int ang = -bAngle/(str1.count()-1)*i;
float tx = -10-(radius+30)*cos(ang*(PI/180));
float ty = (radius+20)*sin(ang*(PI/180));
//压缩y坐标
p.drawText(QPointF(tx, ty), QString("%1").arg(str1[i]));
}
QString str2(" 高温模式");
p.setPen(Qt::red);
for(int i=0; i<str2.count(); i++)
{
// 按正弦函数绘制
int bAngle = 180;
int ang = -bAngle/(str2.count()-1)*i;
float tx = -10-(radius+30)*cos(ang*(PI/180));
float ty = (radius+20)*sin(ang*(PI/180));
//压缩y坐标
p.drawText(QPointF(tx, ty), QString("%1").arg(str2[i]));
}
#endif
}
void UMeter::setConicalGradientColor(QPainter &p, QColor a,QColor b,QColor c,QColor d,const QPointF ¢er, qreal startAngle)
{
QConicalGradient conicalGradient(center,startAngle);
conicalGradient.setColorAt(0,a);
conicalGradient.setColorAt(0.5,b);
conicalGradient.setColorAt(0.75,c);
conicalGradient.setColorAt(1,d);
conicalGradient.setSpread(QGradient::PadSpread);
QPen pen = QPen(QBrush(conicalGradient),15);
p.setPen(pen);
}
void UMeter::setLinearGradientColor(QPainter &p, QColor a,QColor b,QColor c,const QPointF &start, const QPointF &finalStop)
{
QLinearGradient lineargradient(start,finalStop);
lineargradient.setColorAt(0,a);
lineargradient.setColorAt(0.5,b);
lineargradient.setColorAt(1,c);
lineargradient.setSpread(QGradient::PadSpread);
QBrush brush = QBrush(lineargradient);
p.setBrush(brush);
}