QPaint绘制自定义仪表盘组件03

网上视频抄的,用来自己看一下,看完就删掉

ui

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QtMath>
#include <QDialog>
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>
#include <QRadialGradient>

#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();
    QTimer *myTimer;


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

protected:
    void paintEvent(QPaintEvent*);
private:
    int degRotate =0;

private:
    void DrawPoint(QPainter&,int);
    void DrawDigital(QPainter&,int);
    void DrawCircle(QPainter&,int);
    void DrawSmallScale(QPainter&,int);
    void DrawBigScale(QPainter&,int);
    void DrawUnit(QPainter&,int);
    void DrawNum(QPainter&,int);
    void DrawPointer(QPainter&,int);
    void drawIndicator(QPainter *painter);
    void DrawCircle_line(QPainter& painter,int radius);
    void DrawCircle_bom(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 DrawCircle_arc(QPainter& painter,int radius);

    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);

private slots:
    void slot_speed_changed();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // setFixedSize() 函数是 QWidget 类的一个成员函数,用于设置窗口的固定大小。
    // 该函数接受两个参数,分别是窗口宽度和高度。
    // 设置后无法通过拖拽窗口的边缘来改变窗口大小,而且,即使添加的控件超出了窗口大小,也不会出现滚动条。
    setFixedSize(1280,800);
    //定时器动态增加时速
    myTimer = new QTimer(this);
    connect(myTimer,SIGNAL(timeout()),this,SLOT(slot_speed_changed()));

}


void MainWindow::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    int width=this->width();
    int height=this->height() - 100;//移动仪表盘的高度
    int radius=((width>height)?height:width)/2.0;//仪表盘的中心位置
    //移动画笔到中下方
    painter.translate(width/2,height*0.6);
    //启用反锯齿
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::NoPen);
    //设置画刷颜色
    painter.setBrush(QColor(138,43,226));
    DrawSmallScale(painter,radius-60);//刻度线
    DrawDigital(painter,radius-90);//刻度数字
    /*所有形状绘画*/
    // DrawCircle_bom(painter,radius-40);  //扇形大圆
    DrawCircle(painter,radius-35);      //渐变发光外扇形
    DrawCircle_arc(painter,radius - 40);//动态扇形环
    DrawPointer(painter,radius-130);//指针
    DrawCircle_line(painter,radius-35); //最外细圆线
    DrawCircle_bom_big(painter,radius-150);//中间大圆
    DrawCircle_bom_shine(painter,radius - 230);//渐变发光内圈
    DrawCircle_bom_small(painter,radius - 200);//中间小圆

    DrawUnit(painter,radius - 390);//单位
    DrawNum(painter,radius-300);//时速
}
//绘制外圈点
void MainWindow::DrawPoint(QPainter& painter,int radius)
{
    //组装点的路径图
    QPainterPath pointPath;
    pointPath.moveTo(-2,-2);
    pointPath.lineTo(2,-2);
    pointPath.lineTo(2,2);
    pointPath.lineTo(0,4);
    pointPath.lineTo(-2,2);
    //绘制13个小点
    for(int i=0;i<13;++i){
        QPointF point(0,0);
        painter.save();
        painter.setBrush(QColor(250,252,78));
        //计算并移动绘图对象中心点
        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.drawPath(pointPath);
        painter.restore();
    }
}

//刻度数字
void MainWindow::DrawDigital(QPainter& painter,int radius)
{
    //设置画笔,画笔默认NOPEN
    painter.setPen(QColor(255,255,255));
    QFont font;
    font.setFamily("Arial");
    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_bom(QPainter& painter,int radius)
{
    //保存绘图对象
    painter.save();
    //计算大小圆路径
    QPainterPath outRing;
    outRing.moveTo(0,0);
    outRing.arcTo(-radius,-radius, 2*radius,2*radius,-30,240);
    outRing.closeSubpath();
    //设置画刷
    painter.setBrush(QColor(14,15,33));

    painter.drawPath(outRing);
    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(8,77,197));
        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_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_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::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::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();
    //设置渐变色k
    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_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::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);

    //绘制121个小点
    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(255,255,255));
        }
        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::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.drawText(-60, -radius + 130, 120, 40,Qt::AlignCenter,QString("当前车速"));

    painter.setPen(QColor(255,255,255,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::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,255,255));
    painter.drawPath(pointPath.subtracted(inRing));
    painter.restore();
}


//动态增加时速画面效果
void MainWindow::slot_speed_changed()
{
    if(direction == 1)//加速
    {
      degRotate++;
      if(degRotate > 240)
          degRotate = 240;
    }
    else if(direction == 0)//减速
    {
        degRotate--;
        if(degRotate < 0)
        {
           degRotate = 0;
            myTimer->stop();
        }
    }
    update();//刷新画面。很重要!
}

//按键按下事件
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;
    }
}

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

main.cpp

cpp 复制代码
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
相关推荐
island13141 小时前
【QT】 控件 -- 显示类
开发语言·数据库·qt
FancySuMMer112 小时前
关于av_get_channel_layout_nb_channels函数
qt·ffmpeg
行十万里人生4 小时前
Qt 控件与布局管理
数据库·qt·microsoft·华为od·华为·华为云·harmonyos
daqinzl4 小时前
Qt调用ffmpeg库录屏并进行UDP组播推流
qt·ffmpeg·udp组播 推流
daqinzl4 小时前
Qt调用FFmpeg库实时播放UDP组播视频流
qt·ffmpeg·udp组播流
咬光空气18 小时前
Qt 5.14.2 学习记录 —— 십구 事件
数据库·qt·学习
geovindu1 天前
Qt Designer and Python: Build Your GUI
开发语言·qt
新之助小锅2 天前
Qt Creator 15.0.0如何更换主题和字体
开发语言·qt
浮梦终焉3 天前
【嵌入式】总结——Linux驱动开发(三)
linux·驱动开发·qt·嵌入式
练小杰3 天前
Linux系统 C/C++编程基础——基于Qt的图形用户界面编程
linux·c语言·c++·经验分享·qt·学习·编辑器