代码一步一步讲,就不写用啥之类的了,暗部走来,自己找使用的类以及使用方法
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)
{//设置画笔,画笔默认NOPENpainter.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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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)
{//设置画笔,画笔默认NOPENpainter.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();//刷新画面
}