#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPainter>
#include <QString>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
//动态增加时速画面效果
void slot_speed_changed();
//绘制指针
void DrawPointer(QPainter& painter, QPoint ¢er, int radius, int degRotate);
// 最外细圆线
void DrawCircle_line(QPainter& painter, QPoint ¢er,int radius, int width);
// 中间大圆
void DrawCircle_bom_big(QPainter& painter, QPoint & center, int radius);
//渐变发光内圈
void DrawCircle_bom_shine(QPainter& painter, QPoint & center, int radius);
//中间小圆
void DrawCircle_bom_small(QPainter& painter, QPoint & center, int radius);
//绘制实时数字
void DrawDbNum(QPainter& painter, QPoint & point);
// 绘制一条中间略粗两边略尖的渐变发光线条
void DrawDbLightLine(QPainter& painter, QPoint & point);
protected:
void paintEvent(QPaintEvent*);
private:
Ui::Widget *ui;
QTimer timer; //定时器
int m_degRotate = 0;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(&timer, &QTimer::timeout, [=]()
{
//动态增加时速画面效果
slot_speed_changed();
});
timer.start(100);
}
Widget::~Widget()
{
delete ui;
timer.stop();
}
//动态增加时速画面效果
void Widget::slot_speed_changed()
{
m_degRotate++;
if(m_degRotate > 250) {
m_degRotate = 0;
}
update();//刷新很重要!
}
//绘制实时数字
void Widget::DrawDbNum(QPainter& painter, QPoint & point)
{
painter.save();
painter.setPen(QColor(255,0,0));
QFont font;
font.setFamily("Arial");
font.setPointSize(20);
painter.setFont(font);
// 根据 QFont 对象创建 QFontMetrics 实例
QFontMetrics font_metrics(painter.font());
QString str = QString::number(m_degRotate) + QString("kb/s");
// 获取文本的长度
int text_width = font_metrics.width(str);
// 获取文本的高度
int text_height = font_metrics.height();
QPoint curPoint = QPoint(point.x() - text_width / 2, point.y() - text_height);
painter.drawText(curPoint, str);
str = "数据传输速率";
text_width = font_metrics.width(str);
QPoint curPoint2 = QPoint(point.x() - text_width / 2, point.y() + text_height);
painter.drawText(curPoint2, str);
painter.restore();
}
// 绘制一条中间略粗两边略尖的渐变发光线条
void Widget::DrawDbLightLine(QPainter& painter, QPoint & point)
{
painter.save();
// 创建白色的画笔,设置较粗的线条和略圆形的线帽
QPen pen(QColor(255, 255, 255));
pen.setWidth(6);
pen.setCapStyle(Qt::RoundCap);
// 创建一个渐变,将颜色从白色渐变到透明色
QLinearGradient gradient(0, point.y() - 100, 0, point.y() + 100);
gradient.setColorAt(0, QColor(255, 255, 255));
gradient.setColorAt(1, QColor(255, 255, 255, 0));
// 设置画笔的颜色为渐变
pen.setBrush(gradient);
// 将这个画笔设置给 QPainter
painter.setPen(pen);
// 绘制一条直线
painter.drawLine(QPoint(point.x() - 100, point.y()), QPoint(point.x() + 100, point.y()));
painter.restore();
}
// 中间小圆
void Widget::DrawCircle_bom_small(QPainter& painter, QPoint & center, int radius)
{
//保存绘图对象
painter.save();
//计算圆的位置和大小
int x = center.x() - radius;
int y = center.y() - radius;
int width = 2 * radius;
int height = 2 * radius;
//创建圆形路径
QPainterPath inCircle;
inCircle.moveTo(center);
inCircle.addEllipse(x, y, width, height);
//设置画刷和画笔
painter.setBrush(QColor(0, 73, 107));
painter.setPen(QColor(255, 255, 255));
//绘制圆形
painter.drawPath(inCircle);
//恢复绘图对象
painter.restore();
}
// 中间大圆
void Widget::DrawCircle_bom_big(QPainter& painter, QPoint & center, int radius)
{
//保存绘图对象
painter.save();
//计算圆的位置和大小
int x = center.x() - radius;
int y = center.y() - radius;
int width = 2 * radius;
int height = 2 * radius;
//创建圆形路径
QPainterPath inCircle;
inCircle.moveTo(center);
inCircle.addEllipse(x, y, width, height);
//设置画刷和画笔
painter.setBrush(QColor(0, 73, 107));
painter.setPen(QColor(255, 255, 255));
//绘制圆形
painter.drawPath(inCircle);
//恢复绘图对象
painter.restore();
}
//渐变发光内圈
void Widget::DrawCircle_bom_shine(QPainter &painter, QPoint ¢er, int radius)
{
painter.save();
//计算圆的位置和大小
int x = center.x() - radius;
int y = center.y() - radius;
int width = 2 * radius;
int height = 2 * radius;
//创建渐变对象
QRadialGradient radialGradient(center, radius, center);
radialGradient.setColorAt(0.5, QColor(10, 68, 185, 150));
radialGradient.setColorAt(1.0, Qt::transparent);
//设置画刷
painter.setBrush(QBrush(radialGradient));
painter.setPen(Qt::transparent);
//计算圆形路径
QPainterPath path;
path.addEllipse(x, y, width, height);
//绘制圆形渐变
painter.setClipPath(path);
painter.drawEllipse(x, y, width, height);
//恢复绘图对象
painter.restore();
}
// 最外细圆线
void Widget::DrawCircle_line(QPainter& painter, QPoint ¢er, int radius, int width)
{
painter.save();
QPainterPath outRing;
QPainterPath inRing;
outRing.moveTo(center);
inRing.moveTo(center);
// 计算弧线的起点和终点位置
QPoint startPoint(center.x() + radius * cos(60 * M_PI / 180), center.y() - radius * sin(60 * M_PI / 180));
QPoint endPoint(center.x() + radius * cos(300 * M_PI / 180), center.y() - radius * sin(300 * M_PI / 180));
outRing.arcTo(center.x() - radius, center.y() - radius, 2 * radius, 2 * radius, -30, 240);
inRing.addEllipse(center.x() - radius + width, center.y() - radius + width, 2 * (radius - width), 2 * (radius - width));
outRing.closeSubpath();
painter.setBrush(QColor(5,228,255));
painter.drawPath(outRing.subtracted(inRing));
painter.restore();
}
// 绘制指针
void Widget::DrawPointer(QPainter& painter, QPoint ¢er, int radius, int degRotate)
{
//组装点的路径图
QPainterPath pointPath;
pointPath.moveTo(0, 0);
pointPath.moveTo(10,0);
pointPath.lineTo(1,-radius);
pointPath.lineTo(-1,-radius);
pointPath.lineTo(-10,0);
pointPath.arcTo(-10,0,20,20,180,180);
QPainterPath inRing;
inRing.addEllipse(-5,-5,10,10);
painter.save();
// 计算绘制相对原点的坐标系
painter.save();
painter.translate(center);
painter.setPen(Qt::transparent);
//计算并选择绘图对象坐标
painter.rotate(degRotate - 120);
painter.setBrush(QColor(0,255,255));
painter.drawPath(pointPath.subtracted(inRing));
painter.restore();
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QPoint center = QPoint(width() / 2, height() / 2);
int radius = qMin(width() / 2, height() / 2);
static int degRotate = 0;
if (degRotate > 120) {
degRotate = 0;
}
//绘制指针
DrawPointer(painter, center, radius - 80, degRotate++);
// 最外细圆线
DrawCircle_line(painter, center, radius - 50, 2);
// 中间大圆
DrawCircle_bom_small(painter, center, radius - 150);
// -80用于调节渐变圆圈的宽度
DrawCircle_bom_shine(painter, center, radius - 200);
//中间小圆
DrawCircle_bom_small(painter, center, radius - 230);
// 绘制文字
QPoint dbrPoint = QPoint(width() / 2, height() / 2);
DrawDbNum(painter, dbrPoint);
// 绘制一条中间略粗两边略尖的渐变发光线条
QPoint curPoint = QPoint(width() / 2, height() / 2);
DrawDbLightLine(painter, curPoint);
}