1 QPaintEvent绘图事件

QPaintEvent 是 Qt 框架中一个重要的事件类,专门用于处理绘图事件。当 Qt 视图组件需要重绘自己的一部分时,就会产生 QPaintEvent 事件。这通常发生在以下几种情况:

  1. 窗口第一次显示时:当窗口或控件第一次出现在屏幕上时,系统会生成一个 QPaintEvent 事件,
    通知窗口进行自身的绘制。
  2. 窗口大小改变时:当用户改变窗口的大小时,窗口的内容通常需要重新绘制以适应新的尺寸。
  3. 窗口部分被遮挡后又重新显示时:如果窗口被其他窗口遮挡,然后又重新露出来,被遮挡的部分通常需要重新绘制。
  4. 手动请求重绘:通过调用 QWidget 的 update() 或 repaint() 方法,可以手动触发重绘事件。
    在 Qt 应用程序中,通常通过重写 QWidget 的 paintEvent(QPaintEvent *) 方法来处理绘制逻辑。例如:
class MyWidget : public QWidget {
protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);
        // 绘制逻辑
    }
};

在 paintEvent 方法中,您可以创建一个 QPainter 对象并使用它来执行绘制操作。 QPainter 可以绘
制各种基本图形,如线条、矩形、椭圆等,还可以绘制文本和图像。重写 paintEvent 是在 Qt 中进行
自定义绘制的标准做法。

2 QPainter画家

2.1 概述

QPainter 是 Qt 库中用于在屏幕上进行绘画的类。它提供了各种绘制功能,比如画线、画图形、画文本等。

以下是一些基本的用法示例:

  1. 初始化 QPainter:首先,您需要一个 QPaintDevice ,比如一个 QWidget 或 QPixmap ,然后使用它来初始化 QPainter 对象。
QPainter painter(this); // 假设在 QWidget 的子类中

设置画笔和画刷:您可以设置画笔(用于描边)和画刷(用于填充)的颜色、样式等。

painter.setPen(Qt::blue); // 设置画笔颜色为蓝色
painter.setBrush(Qt::yellow); // 设置画刷颜色为黄色

绘制图形:使用 QPainter 的方法来绘制线条、矩形、圆形、文本等。

painter.drawLine(10, 10, 100, 100); // 画线
painter.drawRect(10, 10, 100, 100); // 画矩形
painter.drawText(10, 10, "Hello, Qt!"); // 画文本

结束绘制:完成绘制后, QPainter 对象会在其析构函数中自动结束绘制。

请注意, QPainter 的使用依赖于 Qt 的事件循环,因此通常在 QWidget 的 paintEvent 或者类似的事
件处理函数中使用它。如果您在 Qt 应用程序中使用 QPainter ,请确保您遵循 Qt 的事件驱动机制。

2.2 渐变色

2.2.1 线性渐变

QLinearGradient 是 Qt 框架中用于创建线性渐变的类。线性渐变是一种从一个颜色平滑过渡到另一个颜色的效果,其变化沿着两个点之间的直线进行。这种渐变在图形用户界面设计中非常常见,用于添加深度、立体感或动态效果。

基本用法

要使用 QLinearGradient ,你需要执行以下几个基本步骤:

  1. 创建 QLinearGradient 对象:指定渐变的起点和终点坐标。
  2. 设置颜色停靠点:在渐变线上定义颜色和相应的位置。
  3. 使用渐变创建 QBrush :用 QLinearGradient 对象来创建一个 QBrush ,然后用它在 QPainter
    中进行绘制。

示例代码

以下是一个创建和使用 QLinearGradient 的示例代码:

#include <QPainter>
#include <QLinearGradient>
void MyWidget::paintEvent(QPaintEvent *) {
    // 创建一个 QLinearGradient 对象
    QLinearGradient linearGradient(0, 0, 100, 100); // 起点(0, 0) 终点(100, 100)
    // 设置颜色停靠点
    linearGradient.setColorAt(0.0, Qt::red); // 起点颜色
    linearGradient.setColorAt(1.0, Qt::blue); // 终点颜色
    // 使用这个渐变创建 QBrush
    QBrush brush(linearGradient);
    // 使用 QBrush 进行绘图
    QPainter painter(this);
    painter.setBrush(brush);
    painter.setPen(Qt::NoPen); // 无边框
    painter.drawRect(this->rect()); // 绘制矩形覆盖整个小部件
}

在这个例子中, QLinearGradient 创建了一个从红色到蓝色的渐变,其方向是从小部件的左上角 (0, 0)到右下角 (100, 100)。

注意事项

  • QLinearGradient 的颜色变化是沿着两个指定点之间的直线进行的。通过改变这些点的位置,你
    可以控制渐变的方向和长度。
  • setColorAt() 方法的第一个参数是一个介于 0.0 和 1.0 之间的浮点数,表示颜色在渐变线上的位
    置。0.0 通常对应于起点,1.0 对应于终点。
  • 你可以设置多个颜色停靠点来创建更复杂的渐变效果。例如,你可以在 0.0 处设置一种颜色,在 0.5处设置另一种颜色,在 1.0 处再设置一种颜色。
  • 使用 QLinearGradient 创建的 QBrush 可以用于填充任何形状,包括矩形、椭圆、多边形等。
    为了获取更好的视觉效果,可以启用 QPainter 的抗锯齿选项( QPainter::Antialiasing )。
  • 请注意,当窗口小部件的大小发生变化时,渐变的效果可能也会随之改变,除非你相应地调整渐变的起点和终点坐标或使用其他方法来适应大小变化。

2.2.2 径向渐变

QRadialGradient 是 Qt 框架中用于创建径向渐变的类。径向渐变是一种从中心点向外部辐射的颜色渐变,通常在中心点有一种颜色,而向外围渐渐变化为另一种颜色。这种渐变非常适合用于模拟光源、阴影或创建圆形的立体感。

基本用法

要使用 QRadialGradient ,你需要执行以下几个基本步骤:

  1. 创建 QRadialGradient 对象:指定渐变的中心点、半径以及焦点(可选)。
  2. 设置颜色停靠点:在径向渐变中定义颜色和对应的位置。
  3. 使用渐变创建 QBrush :利用 QRadialGradient 对象创建一个 QBrush ,然后用它在 QPainter 中进行绘制。

示例代码

以下是一个创建和使用 QRadialGradient 的示例代码:

#include <QPainter>
#include <QRadialGradient>
void MyWidget::paintEvent(QPaintEvent *) {
    // 创建一个 QRadialGradient 对象
    QRadialGradient radialGradient(50, 50, 50); // 中心和半径 (50, 50, 50)
    // 可选:设置焦点
    // radialGradient.setFocalPoint(30, 30);
    // 设置颜色停靠点
    radialGradient.setColorAt(0.0, Qt::yellow); // 中心颜色
    radialGradient.setColorAt(1.0, Qt::black); // 外围颜色
    // 使用这个渐变创建 QBrush
    QBrush brush(radialGradient);
    // 使用 QBrush 进行绘图
    QPainter painter(this);
    painter.setBrush(brush);
    painter.setPen(Qt::NoPen); // 无边框
    painter.drawRect(this->rect()); // 绘制矩形覆盖整个小部件
}

在这个例子中, QRadialGradient 创建了一个从中心的黄色向外围的黑色渐变。渐变的中心和半径都设置在 (50, 50, 50)。

注意事项

  • setColorAt() 方法的第一个参数是一个介于 0.0 和 1.0 之间的浮点数,表示颜色在径向渐变中的
    位置。0.0 通常对应于中心点,1.0 对应于边缘。
  • 通过添加多个颜色停靠点,你可以创建更复杂的径向渐变效果。
  • setFocalPoint() 方法允许你设置焦点位置,这是渐变颜色开始变化的点,可以与中心点不同。
    使用 QRadialGradient 创建的 QBrush 可以用于填充任何形状,如矩形、椭圆、多边形等。
  • 为了获得更好的视觉效果,可以启用 QPainter 的抗锯齿选项( QPainter::Antialiasing )。
  • 当绘制较大区域时,可以通过调整渐变的半径和中心点来控制渐变效果的扩展。
  • QRadialGradient 非常适用于创建像按钮、指示灯或其他需要有深度感和立体感的界面元素。

2.2.3 圆锥形渐变

QConicalGradient 是 Qt 框架中用于创建圆锥形渐变的类。圆锥渐变是一种渐变效果,其中颜色沿着
圆锥的轮廓变化,类似于旋转颜色轮。这种渐变以其中心点为基点,颜色沿圆周分布,可以创建出富有动感的视觉效果。

基本用法

要使用 QConicalGradient ,你通常需要做以下几个步骤:

  1. 创建 QConicalGradient 对象:指定渐变的中心点和起始角度。
  2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。
  3. 使用渐变创建 QBrush :使用这个渐变对象来创建一个 QBrush ,然后应用到 QPainter 中进行绘图。

示例代码

下面是一个如何创建和使用 QConicalGradient 的简单示例:

#include <QPainter>
#include <QConicalGradient>
void MyWidget::paintEvent(QPaintEvent *) {
    // 创建一个 QConicalGradient 对象
    QConicalGradient conicalGradient(100, 100, 0); // 中心点 (100, 100),起始角度 0
    // 添加颜色停靠点
    conicalGradient.setColorAt(0.0, Qt::red);
    conicalGradient.setColorAt(0.5, Qt::blue);
    conicalGradient.setColorAt(1.0, Qt::red);
    // 使用这个渐变创建 QBrush
    QBrush brush(conicalGradient);
    // 使用 QBrush 进行绘图
    QPainter painter(this);
    painter.setBrush(brush);
    painter.setPen(Qt::NoPen); // 无边框
    painter.drawRect(this->rect()); // 绘制矩形覆盖整个小部件
}

在这个例子中, QConicalGradient 被用来创建一个从红色到蓝色再回到红色的渐变。渐变的中心设置在点 (100, 100),并且从 0 度开始旋转。

注意事项

  • QConicalGradient 的颜色是沿着圆周分布的,其中 0.0 和 1.0 在圆周上是相同的位置。你可以通过添加多个颜色停靠点来创建更复杂的渐变效果。
  • QConicalGradient在使用时,角度是按照顺时针方向测量的,起始点(0度)通常在三点钟方向。
  • 为了达到最佳的渲染效果,可以启用 QPainter 的抗锯齿渲染提示( QPainter::Antialiasing )。
  • QConicalGradient 非常适合用于创建旋转或动态效果的图形,例如加载指示器、进度条或任何需
    要圆周颜色变化的场景。

3 坐标转移

在 Qt 框架中, painter.translate(rect().center()) 这行代码的作用是移动 QPainter 的坐标系统
原点到当前绘制区域(即由 rect() 返回的矩形)的中心。
解释一下各个部分:

  1. painter : 这是一个 QPainter 对象实例,用于在 Qt 窗口或者图像上进行绘制。
  2. translate() : 这是 QPainter 类中的一个方法,用于改变坐标系统的原点。它接受一个 QPoint 或
    QPointF 作为参数,这个点指定了新的原点位置。
  3. rect() : 这通常是指一个控件(如 QWidget)的矩形区域,返回一个 QRect 或 QRectF 对象,表示该控件的大小和位置。
  4. rect().center() : 这个方法返回当前矩形(即控件的区域)的中心点,是一个 QPoint 或
    QPointF 对象。总之, painter.translate(rect().center()) 这行代码将 QPainter 的绘图原点移动到控件的中心。这在进行中心对称绘制或者需要以控件中心为基准进行绘图时特别有用。

4 画雷达案例

在这里插入图片描述

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QPainter>
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //实例化刷新界面定时器
    timer = new QTimer(this);
    //界面刷新绑定信号与槽
    connect(timer,&QTimer::timeout,this,[=](){
        startAngle += 30;
        if(startAngle >= 360){
            startAngle = 0;
        }
        update();
    });

    timer->setInterval(100);
    timer->start();
}

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

void Widget::paintEvent(QPaintEvent *event)
{
    //定义画家对象
    QPainter painter(this);
    //设置抗锯齿
    painter.setRenderHint(QPainter::Antialiasing,true);
    //定义黑色画刷
    QBrush brush(Qt::black);
    //画刷给画家
    painter.setBrush(brush);
    //矩形界面画黑色
    painter.drawRect(rect());

    //坐标原点移动到中心
    painter.translate(rect().center());
    //设置最小圆半径
    int rEve = height()/2/7;
    //设置渐变半径
    int rTmp = rEve*7;
    //定义绿色画笔对象
    QPen pen(Qt::green,4);
    //画笔给画家
    painter.setPen(pen);
    //画家丢掉画刷
    painter.setBrush(Qt::NoBrush);
    //循环画圆
    for(int i = 1;i <= 7;i++){
        painter.drawEllipse(QPoint(0,0),rEve*i,rEve*i);
    }
    //画雷达坐标系横线
    painter.drawLine(-rEve*7,0,rEve*7,0);
    //画雷达坐标系竖线
    painter.drawLine(0,-rEve*7,0,rEve*7);

    //定义锥形渐变对象
    QConicalGradient conicalGradient(0,0,-startAngle);
    //设置各部分颜色比率
    conicalGradient.setColorAt(0,QColor(0,255,0,200));
    conicalGradient.setColorAt(0.1,QColor(0,255,0,100));
    conicalGradient.setColorAt(0.2,QColor(0,255,0,0));
    conicalGradient.setColorAt(1,QColor(0,255,0,0));
    //设置渐变色画刷
    painter.setBrush(conicalGradient);
    //丢掉画笔
    painter.setPen(Qt::NoPen);
    painter.drawPie(QRect(-rTmp,-rTmp,rTmp*2,rTmp*2),-startAngle*16,70*16);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    Ui::Widget *ui;
    //定义刷新界面定时器
    QTimer *timer;
    //定义起始角度变量
    int startAngle = 0;
};
#endif // WIDGET_H

5 汽车仪表表盘基础版

在这里插入图片描述

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QPainter>
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //实例化刷新界面定时器
    timer = new QTimer(this);
    //界面刷新绑定信号与槽
    connect(timer,&QTimer::timeout,this,[=](){
        startAngle += 30;
        if(startAngle >= 360){
            startAngle = 0;
        }
        update();
    });

    timer->setInterval(100);
    timer->start();
}

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

void Widget::paintEvent(QPaintEvent *event)
{
    //定义画家对象
    QPainter painter(this);
    //设置抗锯齿
    painter.setRenderHint(QPainter::Antialiasing,true);
    //定义黑色画刷
    QBrush brush(Qt::black);
    //画刷给画家
    painter.setBrush(brush);
    //矩形界面画黑色
    painter.drawRect(rect());

    //坐标原点移动到中心
    painter.translate(rect().center());
    //设置最小圆半径
    int rEve = height()/2/7;
    //设置渐变半径
    int rTmp = rEve*7;
    //定义绿色画笔对象
    QPen pen(Qt::green,4);
    //画笔给画家
    painter.setPen(pen);
    //画家丢掉画刷
    painter.setBrush(Qt::NoBrush);
    //循环画圆
    for(int i = 1;i <= 7;i++){
        painter.drawEllipse(QPoint(0,0),rEve*i,rEve*i);
    }
    //画雷达坐标系横线
    painter.drawLine(-rEve*7,0,rEve*7,0);
    //画雷达坐标系竖线
    painter.drawLine(0,-rEve*7,0,rEve*7);

    //定义锥形渐变对象
    QConicalGradient conicalGradient(0,0,-startAngle);
    //设置各部分颜色比率
    conicalGradient.setColorAt(0,QColor(0,255,0,200));
    conicalGradient.setColorAt(0.1,QColor(0,255,0,100));
    conicalGradient.setColorAt(0.2,QColor(0,255,0,0));
    conicalGradient.setColorAt(1,QColor(0,255,0,0));
    //设置渐变色画刷
    painter.setBrush(conicalGradient);
    //丢掉画笔
    painter.setPen(Qt::NoPen);
    painter.drawPie(QRect(-rTmp,-rTmp,rTmp*2,rTmp*2),-startAngle*16,70*16);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    Ui::Widget *ui;
    //定义刷新界面定时器
    QTimer *timer;
    //定义起始角度变量
    int startAngle = 0;
};
#endif // WIDGET_H

5 汽车仪表表盘Pro版

在这里插入图片描述

main.c

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.c

#include "widget.h"
#include "ui_widget.h"
#include <QtMath>

#include <QPainter>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //固定窗口大小
    setFixedSize(800,600);
    //算出一个刻度需要旋转的角度
    angle = 240*1.0/60; //270*1.0的作用是扩大变量类型,把int型口达成double
    //指针角度当前值
    currentValue = 0;
    //指针旋转方向标志位
    mark = 0;
    //设置刷新定时器
    setRefreshTimer();
}

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

//绘图事件函数
void Widget::paintEvent(QPaintEvent *event)
{
    //实例化一个画家对象
    QPainter painter(this);
    //定义半径
    int radius = height()/2;
    //初始化画布
    initCanvas(painter);
    //画小圆
    drawMiddleCircle(painter,60);
    //画刻度
    drawScale(painter,radius);
    //画刻度文字
    drawScaleText(painter,radius);
    //画指针
    drawPointLine(painter,radius);
    //画扇形
    drawSpeedPie(painter,radius);
    //画红色渐变内圈
    drawEllipseInnerShine(painter,120);
    //画黑色内圈
    drawEllipseInnerBlack(painter,80);
    //画当前速度值
    drawCurrentSpeed(painter);
    //画半透明红色外圈
    drawEllipseOutterShine(painter,radius + 20);
    //画汽车logo
    drawLogo(painter,radius);
}

//初始化画布
void Widget::initCanvas(QPainter &painter)
{
    //设置抗锯齿效果
    painter.setRenderHint(QPainter::Antialiasing);
    //底色弄成黑色
    painter.setBrush(Qt::black);
    painter.drawRect(rect());
    //坐标轴平移到中心位置
    QPoint center(rect().width()/2,rect().height()*0.6);
    painter.translate(center);
}

// 画小圆
void Widget::drawMiddleCircle(QPainter &painter, int radius)
{
    painter.setPen(QPen(Qt::white,3));
    painter.drawEllipse(QPoint(0,0),60,60);
}

//画当前速度值
void Widget::drawCurrentSpeed(QPainter &painter)
{
    QFont font("Arial",30);
    font.setBold("true");
    painter.setPen(Qt::white);
    painter.setFont(font);
    painter.drawText(QRect(-60,-60,120,70),Qt::AlignCenter,QString::number(currentValue*4));

    QFont font2("Arial",15);
    painter.setPen(Qt::white);
    painter.setFont(font2);
    painter.drawText(QRect(-60,-60,120,170),Qt::AlignCenter,"Km/h");
}

//画刻度
void Widget::drawScale(QPainter &painter, int radius)
{

    //设置第一个刻度的位置
    painter.save();     //保存当前原点状态,x在三点钟方向
    painter.setPen(QPen(Qt::white,5));  //设置画笔颜色粗细
    painter.rotate(150);
    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.setPen(QPen(Qt::white,5));
        painter.rotate(angle);  //坐标轴旋转240/50度
    }
    painter.restore();
}

//画刻度文字
void Widget::drawScaleText(QPainter &painter, int radius)
{
    int r = radius - 45;
    QFont font("Arial",15);
    font.setBold("true");

    //坐标系x轴恢复到3点钟方向
    painter.restore();
    painter.setFont(font);
    for(int i =0;i <= 60;i++){
        if(i%5 == 0){
            //保存坐标系
            painter.save();
            //算出平移点
            int delX = qCos(qDegreesToRadians(210 - angle*i)) * r;
            int delY = qSin(qDegreesToRadians(210 - angle*i)) * r;
            //平移坐标系
            painter.translate(QPoint(delX,-delY));
            //旋转坐标系以旋转文字方向
            painter.rotate(-120 + angle*i);
            //写上文字
            painter.drawText(-30,-15,50,30,Qt::AlignCenter,QString::number(i*4));
            //恢复坐标系
            painter.restore();
        }
    }
}

//画指针,线
void Widget::drawPointLine(QPainter &painter, int len)
{
    //保存坐标轴原点状态
    painter.save();
    //定义三角型指针起始位置
    static const QPointF points[4] = {
        QPointF(0,0),
        QPointF(200.0,-1.1),
        QPointF(200.0, 1.1),
        QPointF(0,10.0)
    };
    //设置白色画刷
    painter.setBrush(QBrush(Qt::white));
    //丢掉边框
    painter.setPen(Qt::NoPen);
    //坐标轴旋转150度+当前角度
    painter.rotate(150 + angle*currentValue);
    //画速度指针
    painter.drawPolygon(points, 4);
    //坐标轴恢复到原点
    painter.restore();
}

//画扇形
void Widget::drawSpeedPie(QPainter &painter, int radius)
{
    //先用矩形框住扇形区域,加58是为了和扇形外边框和指针头贴合,减116是为了让矩形几何中心和圆形中心重合
    QRect rentangle(-radius,-radius,height(),height());
    //丢掉画笔
    painter.setPen(Qt::NoPen);
    //扇形画刷给画家
    painter.setBrush(QColor(255,0,0,150));
    painter.drawPie(rentangle,(360-150) * 16,-angle*currentValue*16);
}

//设置刷新定时器
void Widget::setRefreshTimer()
{
    //实例化刷新定时器
    timer = new QTimer(this);
    //绑定timer信号与槽
    connect(timer,&QTimer::timeout,this,[=](){
        if(mark == 0){
            currentValue++;
            if(currentValue >= 61){
                mark = 1;
            }
        }else if(mark == 1){
            currentValue--;
            if(currentValue <= 0){
                mark = 0;
            }
        }

        update();
    });

    timer->start(50);
}

//画黑色内圈
void Widget::drawEllipseInnerBlack(QPainter &painter, int radius)
{
    painter.setBrush(QBrush(Qt::black));
    painter.drawEllipse(QPoint(0,0),radius,radius);
}

//画半透明内圈
void Widget::drawEllipseInnerShine(QPainter &painter, int radius)
{
    //径向渐变
    QRadialGradient radialGradient(0,0,radius);
    radialGradient.setColorAt(0.1,QColor(255,0,0,200));
    radialGradient.setColorAt(1,QColor(255,0,0,100));
    painter.setBrush(QBrush(radialGradient));

    painter.drawEllipse(QPoint(0,0),radius,radius);
}

//画半透明红色外圈
void Widget::drawEllipseOutterShine(QPainter &painter, int radius)
{
    //径向渐变
    QRadialGradient radialGradient(0,0,radius);
    //先用矩形框住扇形区域,加58是为了和扇形外边框和指针头贴合,减116是为了让矩形几何中心和圆形中心重合
    QRect rentangle(-radius,-radius,radius*2,radius*2);
    //设置渐变程度
    radialGradient.setColorAt(0.1,QColor(255,0,0,0));
    radialGradient.setColorAt(0.8,QColor(255,0,0,0));
    radialGradient.setColorAt(0.9,QColor(255,0,0,10));
    radialGradient.setColorAt(1,QColor(255,0,0,200));
    //设置渐变画刷
    painter.setBrush(QBrush(radialGradient));
    //丢掉画笔
    painter.setPen(Qt::NoPen);
    painter.drawPie(rentangle,(360-150) * 16,-angle*60*16);
}

//画汽车logo
void Widget::drawLogo(QPainter &painter, int radius)
{
    QRect rectangle(-60,radius*0.5,120,50);
    painter.drawPixmap(rectangle,QPixmap(":/icon.png"));
}

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();

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    Ui::Widget *ui;
    //定义页面刷新定时器
    QTimer *timer;
    //定义指针刻度当前值
    int currentValue;
    //定义指针旋转方向标志位
    int mark;
    //定义一个刻度需要旋转的角度
    double angle;
    //初始化画布
    void initCanvas(QPainter &painter);
    //画小圆
    void drawMiddleCircle(QPainter &painter,int radius);
    //画当前速度
    void drawCurrentSpeed(QPainter &painter);
    //画刻度
    void drawScale(QPainter &painter,int radius);
    //画刻度文字
    void drawScaleText(QPainter &painter,int radius);
    //画指针
    void drawPointLine(QPainter &painter,int len);
    //画扇形
    void drawSpeedPie(QPainter &painter,int radius);
    //设置刷新定时器
    void setRefreshTimer();
    //画黑色内圈
    void drawEllipseInnerBlack(QPainter &painter,int radius);
    //画半透明内圈
    void drawEllipseInnerShine(QPainter &painter,int radius);
    //画半透明红色外圈
    void drawEllipseOutterShine(QPainter &painter,int radius);
    //画汽车logo
    void drawLogo(QPainter &painter,int radius);
};
#endif // WIDGET_H
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐