QT绘画仪表盘

代码一步一步讲,就不写用啥之类的了,暗部走来,自己找使用的类以及使用方法

1、创建工程

2、重载paintEvent

#include <QMainWindow>
#include <QPainter>
#include <QPaintEvent>
protected:
    virtual void paintEvent(QPaintEvent *event);
void MainWindow::paintEvent(QPaintEvent *event)
{

}

3、构建绘画对象,调整表盘位置、画笔位置、刷子之类的

    //创建对象
    QPainter m_painter(this);
    //表盘宽度不变,高度-100,中心位置在前面两个小的的中间
    int m_width = this->width();
    int m_height = this->height() - 100;
    int radius = ((m_width > m_height)?m_height:m_width)/2.0;
    //移动画笔到中下方位置
    m_painter.translate(m_width/2,m_height*0.6);
    //启用反锯齿
    m_painter.setRenderHint(QPainter::Antialiasing, true);
    m_painter.setPen(Qt::NoPen);
    //设置画刷颜色
    m_painter.setBrush(QColor(138,43,226));

4、画刻度线

//刻度线
    DrawSmallScale(m_painter, radius - 60);
private:
    void DrawSmallScale(QPainter & painter, int radius);
void MainWindow::DrawSmallScale(QPainter & painter, int radius)
{
    //组装点路径图(刻度)
    QPainterPath pointPath_small;
    pointPath_small.moveTo(-2, -2);
    pointPath_small.lineTo(2, -2);
    pointPath_small.lineTo(2, 8);
    pointPath_small.lineTo(-2, 8);

    QPainterPath pointPath_big;
    pointPath_big.moveTo(-2, -2);
    pointPath_big.lineTo(2, -2);
    pointPath_big.lineTo(2, 20);
    pointPath_big.lineTo(-2, 20);

    //绘制61个小点
    for(int i = 0; i < 121; i += 2)
    {
        QPointF point(0, 0);
        painter.save();
        point.setX(radius* qCos(((210-i*2)*M_PI)/180));
        point.setY(radius* qSin(((-210+i*2)*M_PI)/180));
        painter.translate(point.x(), point.y());
        painter.rotate(-120+i*2);

        if(i<80)
        {
            painter.setBrush(QColor(0, 0, 0));
        }
        if(i>=80)
        {
            painter.setBrush(QColor(235, 70, 70));
        }
        if(i%5 == 0)
        {
            painter.drawPath(pointPath_big);//绘画大刻度
        }
        else
        {
            painter.drawPath(pointPath_small);//绘画小刻度
        }
        painter.restore();
    }
}

5、刻度数字

    //刻度数字
    DrawDigital(m_painter, radius - 90);
void DrawDigital(QPainter & painter, int radius);
void MainWindow::DrawDigital(QPainter &painter, int radius)
{
    //设置画笔,画笔默认NOPEN
    painter.setPen(QColor(0, 0, 0));
    QFont font;
    font.setFamily("Arical");
    font.setPointSize(15);
    font.setBold(true);
    painter.setFont(font);
    for(int i=0;i<13;++i)
    {
        QPointF point(0, 0);
        painter.save();
        point.setX(radius* qCos(((210-i*20)*M_PI)/180));
        point.setY(radius* qSin(((210-i*20)*M_PI)/180));
        painter.translate(point.x(), -point.y());
        painter.rotate(-120+i*20);
        painter.drawText(-25, 0, 50, 20, Qt::AlignCenter, QString::number(i*20));
        painter.restore();
    }
    //还原画笔
    painter.setPen(Qt::NoPen);
}

6、逐渐发光外扇形

/*所有形状绘画*/
    //逐渐发光外扇形
    DrawCircle(m_painter, radius - 35);
void DrawCircle(QPainter & painter, int radius);
void MainWindow::DrawCircle(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath outRing;
    QPainterPath inRing;
    outRing.moveTo(0,0);
    inRing.moveTo(0,0);
    outRing.arcTo(-radius, -radius, 2*radius, 2*radius, -30, 240);
    inRing.addEllipse(-radius+50, -radius+50, 2*(radius-50), 2*(radius-50));
    outRing.closeSubpath();
    //设置渐变色
    QRadialGradient radialGradient(0,0,radius,0,0);
    radialGradient.setColorAt(1, QColor(0,82,199));
    radialGradient.setColorAt(0.92, Qt::transparent);
    //设置画刷
    painter.setBrush(radialGradient);
    //大圆减小圆
    painter.drawPath(outRing.subtracted(inRing));
    //恢复
    painter.restore();
}

7、指针

void DrawPointer(QPainter & painter, int radius);
//指针
    DrawPointer(m_painter, radius-130);
void MainWindow::DrawPointer(QPainter &painter, int radius)
{
    //组装点路径图
    QPainterPath pointPath;
    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.rotate(degRotate-120);
    painter.setBrush(QColor(255,0,0));
    painter.drawPath(pointPath.subtracted(inRing));
    painter.restore();
}

8、最外细圆圈

void DrawCircle_line(QPainter & painter, int radius);
//最外细圆圈
    DrawCircle_line(m_painter, radius-35);
void MainWindow::DrawCircle_line(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath outRing;
    QPainterPath inRing;
    outRing.moveTo(0,0);
    inRing.moveTo(0,0);
    outRing.arcTo(-radius,-radius,2*radius,2*radius,-30,240);
    inRing.addEllipse(-radius+2,-radius+2,2*(radius-2),2*(radius-2));
    outRing.closeSubpath();

    //设置画刷
    painter.setBrush(QColor(5,228,255));
    //大圆减小圆
    painter.drawPath(outRing.subtracted(inRing));
    painter.restore();
}

9、中间大圆

void DrawCircle_bom_big(QPainter & painter, int radius);
//中间大圆
    DrawCircle_bom_big(m_painter, radius-150);
void MainWindow::DrawCircle_bom_big(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath inRing;
    inRing.moveTo(0,0);
    inRing.addEllipse(-radius+50,-radius+50,2*(radius-50),2*(radius-50));
    //设置画刷
    painter.setBrush(QColor(10,20,30));
    painter.drawPath(inRing);
    painter.restore();
}

10、逐渐发光内圈

void DrawCircle_bom_shine(QPainter & painter, int radius);
//逐渐发光内圈
    DrawCircle_bom_shine(m_painter, radius-230);
void MainWindow::DrawCircle_bom_shine(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //渐变色
    QRadialGradient radialGradient(0,0,radius,0,0);
    radialGradient.setColorAt(0.5,QColor(10,68,185,150));
    radialGradient.setColorAt(1.0,Qt::transparent);
    painter.setBrush(QBrush(radialGradient));
    painter.drawRect(-radius,-radius,2*radius,2*radius);
    painter.restore();
}

11、中间小圆

void DrawCircle_bom_small(QPainter & painter, int radius);
//中间小圆
    DrawCircle_bom_small(m_painter, radius-200);
void MainWindow::DrawCircle_bom_small(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath inRing;
    inRing.moveTo(0,0);
    inRing.addEllipse(-radius+50,-radius+50,2*(radius-50),2*(radius-50));
    //设置画刷
    painter.setBrush(QColor(10,20,30));
    painter.drawPath(inRing);
    painter.restore();
}

12、动态扇形环

void DrawCircle_arc(QPainter & painter, int radius);
//动态扇形环
    DrawCircle_arc(m_painter, radius-40);
void MainWindow::DrawCircle_arc(QPainter &painter, int radius)
{
    QRect rect(-radius, -radius, 2*radius, 2*radius);
    QConicalGradient Conical(0,0,-70);

    Conical.setColorAt(0.1, QColor(255,88,127,200));//红色
    Conical.setColorAt(0.5, QColor(53,179,251,150));//蓝色
    painter.setBrush(Conical);
    painter.drawPie(rect, 210*16, -(degRotate)*16);
}

由于是动态的,需要加入定时器与按键事件模拟加减速

13、单位与时速

固定下窗口大小

setFixedSize(1280,800);

定义一些全局变量

private:
    int degRotate = 0;
    int radius;//仪表盘中心位置
    int direction;//指针运动的方向,1为前进,0为后退

画表盘文字

void DrawUnit(QPainter & painter, int radius);
    void DrawNum(QPainter & painter, int radius);
//单位
    DrawUnit(m_painter,radius-390);
    //时速
    DrawNum(m_painter,radius-300);
void MainWindow::DrawUnit(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //设置笔
    painter.setPen(QColor(255,255,255));
    //设置字体
    QFont font;
    font.setFamily("Arial");
    font.setPointSize(16);
    font.setBold(true);
    painter.setFont(font);
    //画文字
    painter.drawText(-50,-radius,100,20,Qt::AlignCenter,QString("km/h"));

    painter.setPen(QColor(0,0,0));
    painter.drawText(-60,-radius+130,120,40,Qt::AlignCenter,QString("当前车速"));

    painter.setPen(QColor(0,0,0,50));
    painter.drawText(-120,-radius+280,250,40,Qt::AlignCenter,QString("-请按space键加速-"));
    painter.restore();
}

void MainWindow::DrawNum(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //设置笔
    painter.setPen(QColor(255,255,255));
    //设置字体
    QFont font;
    font.setFamily("Arial");
    font.setPointSize(45);
    painter.setFont(font);
    //写文字
    painter.drawText(-75,-radius-20,150,100,Qt::AlignCenter,QString::number(degRotate));
    painter.restore();
}

14、按键事件

添加定时器和按键事件的头文件

#include <QTimer>
#include <QKeyEvent>

重写按键虚函数

    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->key() == Qt::Key_Space)
    {
        if(direction == 0)
        {
            myTimer->start(1);
            direction = 1;
        }
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->key() == Qt::Key_Space)
        direction = 0;
}

构建定时器对象

private:
    int degRotate = 0;
    int radius;//仪表盘中心位置
    int direction;//指针运动的方向,1为前进,0为后退
    QTimer *myTimer;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setFixedSize(1280,800);
    
    //定时器
    myTimer = new QTimer(this);
    connect(myTimer, SIGNAL(timeout()), this, SLOT(slot_seed_changed()));
}

新建速度变化的槽函数

private slots:
    void slot_seed_changed();
void MainWindow::slot_seed_changed()
{
    if(direction == 1)//加速
    {
        degRotate++;
        if(degRotate > 240)
        {
            degRotate = 240;
        }
    }
    else if(direction == 0)//减速
    {
        degRotate--;
        if(degRotate<0)
        {
            degRotate = 0;
            myTimer->stop();
        }
    }
    update();//刷新画面
}

15、动画效果

汽车仪表盘

16、完整代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPainter>
#include <QPaintEvent>
#include <QtMath>

#include <QTimer>
#include <QKeyEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

protected:
    virtual void paintEvent(QPaintEvent *event);
    virtual void keyPressEvent(QKeyEvent *event);
    virtual void keyReleaseEvent(QKeyEvent *event);

private:
    void DrawSmallScale(QPainter & painter, int radius);
    void DrawDigital(QPainter & painter, int radius);
    void DrawCircle(QPainter & painter, int radius);
    void DrawCircle_arc(QPainter & painter, int radius);
    void DrawPointer(QPainter & painter, int radius);
    void DrawCircle_line(QPainter & painter, int radius);
    void DrawCircle_bom_big(QPainter & painter, int radius);
    void DrawCircle_bom_shine(QPainter & painter, int radius);
    void DrawCircle_bom_small(QPainter & painter, int radius);
    void DrawUnit(QPainter & painter, int radius);
    void DrawNum(QPainter & painter, int radius);


private:
    int degRotate = 0;
    int radius;//仪表盘中心位置
    int direction;//指针运动的方向,1为前进,0为后退
    QTimer *myTimer;

private slots:
    void slot_seed_changed();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setFixedSize(1280,800);

    //定时器
    myTimer = new QTimer(this);
    connect(myTimer, SIGNAL(timeout()), this, SLOT(slot_seed_changed()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    //创建对象
    QPainter m_painter(this);
    //表盘宽度不变,高度-100,中心位置在前面两个小的的中间
    int m_width = this->width();
    int m_height = this->height() - 100;
    int radius = ((m_width > m_height)?m_height:m_width)/2.0;
    //移动画笔到中下方位置
    m_painter.translate(m_width/2,m_height*0.6);
    //启用反锯齿
    m_painter.setRenderHint(QPainter::Antialiasing, true);
    m_painter.setPen(Qt::NoPen);
    //设置画刷颜色
    m_painter.setBrush(QColor(138,43,226));
    //刻度线
    DrawSmallScale(m_painter, radius - 60);
    //刻度数字
    DrawDigital(m_painter, radius - 90);

    /*所有形状绘画*/
    //逐渐发光外扇形
    DrawCircle(m_painter, radius - 35);
    //动态扇形环
    DrawCircle_arc(m_painter, radius-40);
    //指针
    DrawPointer(m_painter, radius-130);
    //最外细圆圈
    DrawCircle_line(m_painter, radius-35);
    //中间大圆
    DrawCircle_bom_big(m_painter, radius-150);
    //逐渐发光内圈
    DrawCircle_bom_shine(m_painter, radius-230);
    //中间小圆
    DrawCircle_bom_small(m_painter, radius-200);

    //单位
    DrawUnit(m_painter,radius-390);
    //时速
    DrawNum(m_painter,radius-300);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Space)
    {
        if(direction == 0)
        {
            myTimer->start(1);
            direction = 1;
        }
    }
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Space)
        direction = 0;
}

void MainWindow::DrawSmallScale(QPainter & painter, int radius)
{
    //组装点路径图(刻度)
    QPainterPath pointPath_small;
    pointPath_small.moveTo(-2, -2);
    pointPath_small.lineTo(2, -2);
    pointPath_small.lineTo(2, 8);
    pointPath_small.lineTo(-2, 8);

    QPainterPath pointPath_big;
    pointPath_big.moveTo(-2, -2);
    pointPath_big.lineTo(2, -2);
    pointPath_big.lineTo(2, 20);
    pointPath_big.lineTo(-2, 20);

    //绘制61个小点
    for(int i = 0; i < 121; i += 2)
    {
        QPointF point(0, 0);
        painter.save();
        point.setX(radius* qCos(((210-i*2)*M_PI)/180));
        point.setY(radius* qSin(((-210+i*2)*M_PI)/180));
        painter.translate(point.x(), point.y());
        painter.rotate(-120+i*2);

        if(i<80)
        {
            painter.setBrush(QColor(0, 0, 0));
        }
        if(i>=80)
        {
            painter.setBrush(QColor(235, 70, 70));
        }
        if(i%5 == 0)
        {
            painter.drawPath(pointPath_big);//绘画大刻度
        }
        else
        {
            painter.drawPath(pointPath_small);//绘画小刻度
        }
        painter.restore();
    }
}

void MainWindow::DrawDigital(QPainter &painter, int radius)
{
    //设置画笔,画笔默认NOPEN
    painter.setPen(QColor(0, 0, 0));
    QFont font;
    font.setFamily("Arical");
    font.setPointSize(15);
    font.setBold(true);
    painter.setFont(font);
    for(int i=0;i<13;++i)
    {
        QPointF point(0, 0);
        painter.save();
        point.setX(radius* qCos(((210-i*20)*M_PI)/180));
        point.setY(radius* qSin(((210-i*20)*M_PI)/180));
        painter.translate(point.x(), -point.y());
        painter.rotate(-120+i*20);
        painter.drawText(-25, 0, 50, 20, Qt::AlignCenter, QString::number(i*20));
        painter.restore();
    }
    //还原画笔
    painter.setPen(Qt::NoPen);
}

void MainWindow::DrawCircle(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath outRing;
    QPainterPath inRing;
    outRing.moveTo(0,0);
    inRing.moveTo(0,0);
    outRing.arcTo(-radius, -radius, 2*radius, 2*radius, -30, 240);
    inRing.addEllipse(-radius+50, -radius+50, 2*(radius-50), 2*(radius-50));
    outRing.closeSubpath();
    //设置渐变色
    QRadialGradient radialGradient(0,0,radius,0,0);
    radialGradient.setColorAt(1, QColor(0,82,199));
    radialGradient.setColorAt(0.92, Qt::transparent);
    //设置画刷
    painter.setBrush(radialGradient);
    //大圆减小圆
    painter.drawPath(outRing.subtracted(inRing));
    //恢复
    painter.restore();
}

void MainWindow::DrawCircle_arc(QPainter &painter, int radius)
{
    QRect rect(-radius, -radius, 2*radius, 2*radius);
    QConicalGradient Conical(0,0,-70);

    Conical.setColorAt(0.1, QColor(255,88,127,200));//红色
    Conical.setColorAt(0.5, QColor(53,179,251,150));//蓝色
    painter.setBrush(Conical);
    painter.drawPie(rect, 210*16, -(degRotate)*16);
}

void MainWindow::DrawPointer(QPainter &painter, int radius)
{
    //组装点路径图
    QPainterPath pointPath;
    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.rotate(degRotate-120);
    painter.setBrush(QColor(255,0,0));
    painter.drawPath(pointPath.subtracted(inRing));
    painter.restore();
}

void MainWindow::DrawCircle_line(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath outRing;
    QPainterPath inRing;
    outRing.moveTo(0,0);
    inRing.moveTo(0,0);
    outRing.arcTo(-radius,-radius,2*radius,2*radius,-30,240);
    inRing.addEllipse(-radius+2,-radius+2,2*(radius-2),2*(radius-2));
    outRing.closeSubpath();

    //设置画刷
    painter.setBrush(QColor(5,228,255));
    //大圆减小圆
    painter.drawPath(outRing.subtracted(inRing));
    painter.restore();
}

void MainWindow::DrawCircle_bom_big(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath inRing;
    inRing.moveTo(0,0);
    inRing.addEllipse(-radius+50,-radius+50,2*(radius-50),2*(radius-50));
    //设置画刷
    painter.setBrush(QColor(10,20,30));
    painter.drawPath(inRing);
    painter.restore();
}

void MainWindow::DrawCircle_bom_shine(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //渐变色
    QRadialGradient radialGradient(0,0,radius,0,0);
    radialGradient.setColorAt(0.5,QColor(10,68,185,150));
    radialGradient.setColorAt(1.0,Qt::transparent);
    painter.setBrush(QBrush(radialGradient));
    painter.drawRect(-radius,-radius,2*radius,2*radius);
    painter.restore();
}

void MainWindow::DrawCircle_bom_small(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath inRing;
    inRing.moveTo(0,0);
    inRing.addEllipse(-radius+50,-radius+50,2*(radius-50),2*(radius-50));
    //设置画刷
    painter.setBrush(QColor(10,20,30));
    painter.drawPath(inRing);
    painter.restore();
}

void MainWindow::DrawUnit(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //设置笔
    painter.setPen(QColor(255,255,255));
    //设置字体
    QFont font;
    font.setFamily("Arial");
    font.setPointSize(16);
    font.setBold(true);
    painter.setFont(font);
    //画文字
    painter.drawText(-50,-radius,100,20,Qt::AlignCenter,QString("km/h"));

    painter.setPen(QColor(0,0,0));
    painter.drawText(-60,-radius+130,120,40,Qt::AlignCenter,QString("当前车速"));

    painter.setPen(QColor(0,0,0,50));
    painter.drawText(-120,-radius+280,250,40,Qt::AlignCenter,QString("-请按space键加速-"));
    painter.restore();
}

void MainWindow::DrawNum(QPainter &painter, int radius)
{
    //保存绘图对象
    painter.save();
    //设置笔
    painter.setPen(QColor(255,255,255));
    //设置字体
    QFont font;
    font.setFamily("Arial");
    font.setPointSize(45);
    painter.setFont(font);
    //写文字
    painter.drawText(-75,-radius-20,150,100,Qt::AlignCenter,QString::number(degRotate));
    painter.restore();
}

void MainWindow::slot_seed_changed()
{
    if(direction == 1)//加速
    {
        degRotate++;
        if(degRotate > 240)
        {
            degRotate = 240;
        }
    }
    else if(direction == 0)//减速
    {
        degRotate--;
        if(degRotate<0)
        {
            degRotate = 0;
            myTimer->stop();
        }
    }
    update();//刷新画面
}



  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值