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);
}
posted @ 2025-05-09 12:04  站着说话不腰疼  阅读(48)  评论(0)    收藏  举报