QT项目——汽车仪表盘
用QT实现汽车仪表盘
文章目录
前言
完整代码:QT实现汽车仪表盘完整代码
一、汽车仪表盘示例
用 QT 实现汽车仪表盘如下:

该示例主要用到了 QPaintEvent 绘图事件,QPainter 的使用。
QPaintEvent 是 Qt 框架中一个重要的事件类,专门用于处理绘图事件。当 Qt 视图组件需要重绘自己的一部分时,就会产生 QPaintEvent 事件。
QPainter 是 Qt 库中用于在屏幕上进行绘画的类。它提供了各种绘制功能,比如画线、画图形、画文本等。
接下来我将一步一步实现该汽车仪表盘。
二、实现代码框架
实现汽车仪表盘,我们可以从两个方面入手,先实现静态界面如仪表盘刻度和数字:

再实现动态界面如速度显示和UI美化:

1. 静态界面实现
静态界面实现步骤如下:
- 初始化画布
- 画小圆
- 画刻度
- 画刻度文字
1.1 初始化画布
实现步骤:
- 重写 paintEvent
- 设置分辨率为 800 * 600
- 将底色设置为黑色
- 将坐标系移到正中间偏下一点的位置(方便后面设置刻度)
代码示例:
protected:
void paintEvent(QPaintEvent *event) override;
private:
void initCanvas(QPainter& painter); // 初始化画布
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置分辨率为800*600
setFixedSize(800,600);
}
void Widget::initCanvas(QPainter& painter)
{
// 启用抗锯齿
painter.setRenderHint(QPainter::Antialiasing, true);
// 设置底色为黑色
painter.setBrush(Qt::black);
painter.drawRect(rect());
// 设置坐标系为中心偏下一点
QPoint cent(rect().width() / 2, rect().height() * 0.6);
painter.translate(cent);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// 初始化画布
initCanvas(painter);
}
在这里我们使用 painter.setRenderHint(QPainter::Antialiasing, true); 可以启用抗锯齿功能,这样在使用 QPainter 进行绘图时,绘制的线条、曲线和文本等会具有更平滑的边缘,提高图像的质量和美观度。
程序运行效果如下:

坐标轴分析:

1.2 画小圆
实现步骤:
- 设置画笔为白色,像素为3
- 画小圆
代码示例:
private:
void drawMiddleCircle(QPainter& painter,int radius); // 画小圆
void Widget::drawMiddleCircle(QPainter &painter, int radius)
{
// 设置画笔颜色为白色,像素为3
painter.setPen(QPen(Qt::white, 3));
// 以坐标为(0,0),x 为 radius,y 为 radius 画椭圆(x = y 时为画圆)
painter.drawEllipse(QPoint(0, 0), radius, radius);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
}
程序运行效果如下:
1.3 画刻度
实现步骤:
- 保存原来坐标位置
- 旋转坐标轴,画刻度
- 恢复原来坐标位置
代码示例:
private:
int startAngle;
double angle;
void drawScale(QPainter& painter,int radius); // 画刻度
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
startAngle = 150;
}
void Widget::drawScale(QPainter &painter, int radius)
{
angle = 240 * 1.0 / 60;
// 保存原来坐标位置
painter.save();
painter.setPen(QPen(Qt::white, 5));
// 旋转坐标轴
painter.rotate(startAngle);
// 画刻度
for (int i = 0; i <= 60; i++)
{
if (i >= 40)
{
painter.setPen(QPen(Qt::red, 5));
}
if (i % 5 == 0)
{
painter.drawLine(radius -20, 0, radius - 3, 0);
}
else
{
painter.drawLine(radius -8, 0, radius - 3, 0);
}
painter.rotate(angle);
}
// 恢复原来坐标位置
painter.restore();
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
}
程序运行效果如下:

坐标轴分析:初始化旋转150°后到达0刻度线位置

1.4 画刻度文字
实现步骤:
- 设置绘图字体样式
- 保存坐标系
- 算出平移坐标点
- 平移坐标系
- 旋转坐标系
- 绘制文字
- 恢复坐标系
代码示例:
private:
void drawScaleText(QPainter& painter,int radius); // 画刻度文字
#include <QtMath>
void Widget::drawScaleText(QPainter &painter, int radius)
{
// 设置绘图字体样式
QFont font("Arial", 15);
// 设置粗体
font.setBold(true);
painter.setFont(font);
int r = radius - 50;
for (int i = 0; i <= 60; i++)
{
if (i % 5 == 0)
{
// 保存坐标系
painter.save();
//算出平移点,弧度=角度*3.1415/180
int x = qCos((210-angle * i) * M_PI / 180) * r;
int y = qSin(qDegreesToRadians(210 - angle * i)) * r; // QT中Sin和Cos默认是弧度
// 平移坐标系
painter.translate(QPoint(x, -y));
// 旋转坐标系
painter.rotate(-120+angle*i);//angle=4,30*4=120的时候,实参是0,120
// 写上文字
painter.drawText(-25, -25, 50, 30, Qt::AlignCenter, QString::number(i * 4));
// 恢复坐标系
painter.restore();
}
}
}
计算平移点解析:

在 QT 中 Sin 和 Cos 默认是弧度,我们可以用 QT 中数学库自带的函数转换
qDegreesToRadians:将度数转化为弧度也可以通过数学公式自行计算:弧度 = 角度 * 3.1415 / 180

程序运行效果如下:

2. 动态界面实现
动态界面实现步骤如下:
- 画指针
- 画扇形
- 画渐变内圈圆
- 画黑色内圈
- 设置当前速度
- 画外环发光圈
- 画一个汽车logo
2.1 画指针
实现步骤:
- 保存坐标系
- 设置画刷和画笔
- 设置多边形的四个顶点坐标
- 旋转画笔
- 绘制多边形
- 恢复坐标系
- 开始定时器,旋转指针
代码示例:
private:
int currentValue;
int mark = 0;
void drawPointLine(QPainter &painter,int lenth); // 画指针
void startSpeed(); // 开启定时器,旋转指针
#include <QTimer>
void Widget::drawPointLine(QPainter &painter, int lenth)
{
// 保存坐标系
painter.save();
painter.setBrush(Qt::white);
// 将画笔设置为无边框
painter.setPen(Qt::NoPen);
// 设置多边形四个顶点坐标
static const QPointF points[4] = {
QPointF(0, 0.0),
QPointF(200.0, -1.1),
QPointF(200.0, 1.1),
QPointF(0, 15.0),
};
// 旋转画笔
painter.rotate(startAngle + angle * currentValue);
// 绘制多边形
painter.drawPolygon(points, 4);
// 恢复坐标系
painter.restore();
}
void Widget::startSpeed()
{
timer = new QTimer(this);
currentValue = 0;
connect(timer, &QTimer::timeout, [=]() {
if (mark == 0)
{
currentValue++;
if (currentValue >= 61)
{
mark = 1;
}
}
if (mark == 1)
{
currentValue--;
if (currentValue == 0)
{
mark = 0;
}
}
update();
});
timer->start(50);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
}
程序运行效果如下:

2.2 画扇形
实现步骤:
- 设置矩形边框
- 设置画笔和画刷
- 画扇形
代码示例:
private:
void drawSpeedPie(QPainter& painter,int radius); // 画扇形
void Widget::drawSpeedPie(QPainter &painter, int radius)
{
// 1. 设置矩形边框
QRect rentangle(-radius, -radius, radius * 2, radius * 2);
// 2. 设置画笔和画刷
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(255, 0, 0, 80));
// 3. 画扇形
painter.drawPie(rentangle, (360 - startAngle) * 16, -angle * currentValue * 16);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
// 画扇形
drawSpeedPie(painter, rad+25);
}
setBrush(QColor(255, 0, 0, 80))方法将画刷设置为半透明的红色,其中RGB值为(255, 0, 0)表示红色,最后一个参数80表示透明度,范围为0(完全透明)到255(完全不透明)。
程序运行效果如下:

2.3 画渐变内圈圆
画渐变内圈圆主要用到 QRadialGradient 类,QRadialGradient 是 Qt 框架中用于创建径向渐变的类。
径向渐变是一种从中心点向外部辐射的颜色渐变,通常在中心点有一种颜色,而向外围渐渐变化为另一种颜色。这种渐变非常适合用于模拟光源、阴影或创建圆形的立体感。
实现步骤:
- 创建 QRadialGradient 对象:指定渐变的中心点、半径
- 设置颜色停靠点:在径向渐变中定义颜色和对应的位置
- 使用渐变创建画刷
- 绘制内圈圆
代码示例:
private:
void drawEllipseInnerShine(QPainter& painter,int radius); // 画渐变内圈圆
void Widget::drawEllipseInnerShine(QPainter &painter, int radius)
{
// 1. 创建 QRadialGradient 对象:指定渐变的中心点、半径
QRadialGradient radialGradient(0, 0, radius);
// 2. 设置颜色停靠点:在径向渐变中定义颜色和对应的位置
radialGradient.setColorAt(0, QColor(255, 0, 0, 200));
radialGradient.setColorAt(1, QColor(0, 0, 0, 100));
// 3. 使用渐变创建画刷
painter.setBrush(radialGradient);
// 4. 绘制内圈圆
painter.drawEllipse(QPoint(0, 0), radius, radius);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
// 画扇形
drawSpeedPie(painter, rad+25);
// 画渐变内圈圆
drawEllipseInnerShine(painter,100);
}
程序运行效果如下:

2.4 画黑色内圈圆
实现步骤:
- 设置画刷
- 绘制内圈圆
代码示例:
private:
void drawEllipseInnerBlack(QPainter& painter,int radius); // 画黑色内圈圆
void Widget::drawEllipseInnerBlack(QPainter &painter, int radius)
{
// 1. 设置画刷
painter.setBrush(Qt::black);
// 2. 绘制内圈圆
painter.drawEllipse(QPoint(0, 0), radius, radius);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
// 画扇形
drawSpeedPie(painter, rad+25);
// 画渐变内圈圆
drawEllipseInnerShine(painter,100);
// 画黑色内圈圆
drawEllipseInnerBlack(painter, 70);
}
程序运行效果如下:

2.5 设置当前速度
实现步骤:
- 设置画笔
- 设置绘图字体样式
- 绘制速度
- 绘制单位
代码示例:
private:
void drawCurrentSpeed(QPainter& painter); // 设置当前速度
void Widget::drawCurrentSpeed(QPainter &painter)
{
// 1. 设置画笔
painter.setPen(Qt::white);
// 2. 设置绘图字体样式
QFont font1("Arial", 30);
font1.setBold(true);
painter.setFont(font1);
// 3. 绘制速度
painter.drawText(QRect(-60, -60, 120, 70), Qt::AlignCenter, QString::number(currentValue * 4));
// 4. 绘制单位 Km/h (同上)
QFont font2("Arial", 13);
font2.setBold(true);
painter.setFont(font2);
painter.drawText(QRect(-60, -60, 120, 160), Qt::AlignCenter, "Km/h");
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
// 画扇形
drawSpeedPie(painter, rad+25);
// 画渐变内圈圆
drawEllipseInnerShine(painter,100);
// 画黑色内圈圆
drawEllipseInnerBlack(painter, 70);
// 设置当前速度
drawCurrentSpeed(painter);
}
程序运行效果如下:

2.6 画外环发光圈
实现步骤:
- 设置矩形边框
- 将画笔设置为无边框
- 创建 QRadialGradient 对象:指定渐变的中心点、半径
- 设置颜色停靠点:在径向渐变中定义颜色和对应的位置
- 使用渐变创建画刷
- 绘制扇形
代码示例:
private:
void drawEllipseOutterShine(QPainter& painter,int radius); // 画外环发光圈
void Widget::drawEllipseOutterShine(QPainter &painter, int radius)
{
// 1. 设置矩形边框
QRect rentangle(-radius, -radius, radius * 2, radius * 2);
// 2. 将画笔设置为无边框
painter.setPen(Qt::NoPen);
// 3. 创建 QRadialGradient 对象:指定渐变的中心点、半径
QRadialGradient radialGradient(0, 0, radius);
// 4. 设置颜色停靠点:在径向渐变中定义颜色和对应的位置
radialGradient.setColorAt(1, QColor(255, 0, 0, 200));
radialGradient.setColorAt(0.97, QColor(255, 0, 0, 120));
radialGradient.setColorAt(0.9, QColor(255, 0, 0, 0));
radialGradient.setColorAt(0, QColor(255, 0, 0, 0));
// 5. 使用渐变创建画刷
painter.setBrush(radialGradient);
// 6. 绘制扇形
painter.drawPie(rentangle, (360 - 150) * 16, -angle * 61 * 16);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
// 画扇形
drawSpeedPie(painter, rad+25);
// 画渐变内圈圆
drawEllipseInnerShine(painter,100);
// 画黑色内圈圆
drawEllipseInnerBlack(painter, 70);
// 设置当前速度
drawCurrentSpeed(painter);
// 画外环发光圈
drawEllipseOutterShine(painter,rad+25);
}
程序运行效果如下:

2.7 画一个汽车logo
实现步骤:
- 设置矩形边框
- 绘制资源图片
添加图片资源:





代码示例:
private:
void drawLogo(QPainter& painter, int radius); // 画汽车logo
void Widget::drawLogo(QPainter &painter, int radius)
{
// 1. 设置矩形边框
QRect rectangle(-65, radius * 0.38, 130, 50);
// 2. 绘制资源图片
painter.drawPixmap(rectangle,QPixmap(":/icon.png"));
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rad = height() / 2;
// 初始化画布
initCanvas(painter);
// 画小圆
drawMiddleCircle(painter, 60);
// 画刻度
drawScale(painter, rad);
// 画刻度文字
drawScaleText(painter, rad);
// 画指针
drawPointLine(painter, rad - 58);
// 画扇形
drawSpeedPie(painter, rad+25);
// 画渐变内圈圆
drawEllipseInnerShine(painter,100);
// 画黑色内圈圆
drawEllipseInnerBlack(painter, 70);
// 设置当前速度
drawCurrentSpeed(painter);
// 画外环发光圈
drawEllipseOutterShine(painter,rad+25);
// 画一个汽车logo
drawLogo(painter, rad);
}
程序运行效果如下:

更多推荐



所有评论(0)