18.Qt使用QPainter实现汽车仪表盘
Qt使用QPainter实现汽车仪表盘
实现效果:

widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QTimer>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
QTimer * timer;
int currentValue = 0;
int mark = 0;
int startAngle = 150;
int redius = height()/2;
//计算1份的角度135;
double angle = 240*1.0/60;//*.1.0的作用是扩大变量类型;
void initCanvas(QPainter &painter);
void drawMiddleCircle(QPainter &painter, int redius);
void drawCurrentSpeed(QPainter &painter, int currentValue);
void drawScale(QPainter &painter, int redius);
void drawScaleFont(QPainter &painter, int redius);
void drawPointLine(QPainter &painter, int len);
void drawSpeedPie(QPainter &painter, int redius);
void drawEllipseInnerBlack(QPainter &painter, int redius);
void drawEllipseInnerShine(QPainter &painter, int redius);
void drawEllipseOutterShine(QPainter &painter, int redius);
void drawLogo(QPainter &painter, int redius);
protected:
void paintEvent(QPaintEvent *event) override;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPaintEvent>
#include <QPainter>
#include <QtMath>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setFixedSize(800,600);
timer = new QTimer(this);
//动态设置指针的指向值
connect(timer,&QTimer::timeout,[=](){
if(mark == 0){
currentValue++;
if(currentValue >= 61)
mark=1;
}
if(mark == 1){
currentValue--;
if(currentValue == 0)
mark=0;
}
update();
});
timer->setInterval(50);
timer->start();
}
Widget::~Widget()
{
delete ui;
}
void Widget::initCanvas(QPainter &painter)
{
//去锯齿
painter.setRenderHint(QPainter::Antialiasing,true);
//底色刷成黑色
painter.setBrush(Qt::black);
painter.drawRect(rect());
//平移坐标点
painter.translate(rect().center());
}
void Widget::drawScale(QPainter &painter, int redius)
{
//保存原点,x在3点钟方向
painter.save();
painter.rotate(startAngle);
painter.setPen(QPen(Qt::white,4));
for (int i = 0;i <= 60;i++) {
if(i*4 >= 160){
painter.setPen(QPen(Qt::red,4));
}
if(i%5 == 0){
//画刻度
painter.drawLine(redius-20,0,redius-3,0);
}else{
painter.drawLine(redius-10,0,redius-3,0);
}
painter.rotate(angle);
}
painter.restore();
}
void Widget::drawScaleFont(QPainter &painter, int redius)
{
QFont font("宋体",15);
font.setBold(true);
painter.setFont(font);
painter.setPen(QPen(Qt::white,2));
//写刻度文字
int r = redius-40;
for (int i = 0;i <= 60;i++) {
if(i%5 == 0){
//保存坐标系
painter.save();
//算出平移点
int delx = qCos(qDegreesToRadians(210-angle*i)) *r;//qt中需要用弧度,使用qDegreesToRadians转换
int dely = qSin(qDegreesToRadians(210-angle*i)) *r;
//平移坐标点
painter.translate(QPoint(delx,-dely));
//旋转坐标系
painter.rotate(-120+angle*i);
//写文字
painter.drawText(-25,-25,50,40,Qt::AlignCenter,QString::number(i*4));
//恢复坐标系
painter.restore();
}
}
painter.setPen(Qt::NoPen);
}
void Widget::drawPointLine(QPainter &painter, int len)
{
//重置原点,设置坐标从0开始
painter.save();
static const QPointF points[4] = {
QPointF(0,0.0),
QPointF(200.0, -1.1),
QPointF(200.0, 1.1),
QPointF(0, 15.0)
};
painter.setBrush(Qt::white);
painter.setPen(Qt::NoPen);
//将绘制的结果进行翻转
painter.rotate(startAngle+ angle*currentValue);
painter.drawPolygon(points, 4);
//painter.drawLine(60,0,len-20-10-28,0);
painter.restore();
}
void Widget::drawSpeedPie(QPainter &painter, int redius)
{
//保存之前原点的坐标x,y
painter.save();
QRect rect(-redius,-redius,redius*2,redius*2);
painter.setBrush(QColor(224,77,39,100));
painter.setPen(Qt::NoPen);
painter.drawPie(rect,(360-startAngle)*16,-angle*currentValue*16);
//恢复之前保存原点的坐标x,y
painter.restore();
}
void Widget::drawEllipseInnerBlack(QPainter &painter, int redius)
{
painter.setBrush(Qt::black);
painter.drawEllipse(QPoint(0,0),redius,redius);
}
void Widget::drawEllipseInnerShine(QPainter &painter, int redius)
{
QRadialGradient radialGrandient(0,0,redius);
radialGrandient.setColorAt(0.0,QColor(255,0,0,150));
radialGrandient.setColorAt(1.0,QColor(0,0,0,150));
painter.setBrush(radialGrandient);
painter.drawEllipse(QPoint(0,0),redius,redius);
}
void Widget::drawEllipseOutterShine(QPainter &painter, int redius)
{
painter.save();
QRect rect(-redius,-redius,redius*2,redius*2);
painter.setBrush(QColor(224,77,39,100));
painter.setPen(Qt::NoPen);
QRadialGradient radialGradient(0,0,redius);
radialGradient.setColorAt(1.0,QColor(255,0,0,200));
radialGradient.setColorAt(0.97,QColor(255,0,0,120));
radialGradient.setColorAt(0.9,QColor(0,0,0,0));
radialGradient.setColorAt(0.0,QColor(0,0,0,0));
painter.setBrush(radialGradient);
painter.drawPie(rect,(360-149)*16,-angle*61*16);
painter.restore();
}
void Widget::drawLogo(QPainter &painter, int redius)
{
QRect rect(-65,redius*0.36,135,50);
painter.drawPixmap(rect,QPixmap(":/icon.png"));
}
void Widget::drawMiddleCircle(QPainter &painter, int redius)
{
painter.setPen(QPen(Qt::white,2));
painter.drawEllipse(QPoint(0,0),redius,redius);
}
void Widget::drawCurrentSpeed(QPainter &painter, int currentValue)
{
painter.setPen(QPen(Qt::white));
QFont font("宋体",30);
font.setBold(true);
painter.setFont(font);
painter.drawText(QRect(-60,-60,120,90),Qt::AlignCenter,QString::number(currentValue));
QFont font2("宋体",13);
font2.setBold(true);
painter.setFont(font2);
painter.drawText(QRect(-60,-60,120,150),Qt::AlignCenter,"Km/h");
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//初始化画布
initCanvas(painter);
//画小圆
//drawMiddleCircle(painter,60);
//画刻度
drawScale(painter,redius);
//画文字
drawScaleFont(painter,redius);
//画指针、线
drawPointLine(painter,redius);
//画扇形
drawSpeedPie(painter,redius);
//画渐变内圈圆
drawEllipseInnerShine(painter,100);
//画内圆
drawEllipseInnerBlack(painter,65);
//当前速度
drawCurrentSpeed(painter,currentValue*4);
//画外环发光圈
drawEllipseOutterShine(painter,redius+20);
//画汽车logo
drawLogo(painter, redius);
}

浙公网安备 33010602011771号