【C++ QT项目4】——QPainter实现模拟雷达与汽车仪表盘

1 QPaintEvent绘图事件

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

  1. 窗口第一次显示时: 当窗口或控件第一次出现在屏幕上时,系统会生成一个 QPaintEvent 事件,通知窗口进行自身的绘制。
  2. 窗口大小改变时: 当用户改变窗口的大小时,窗口的内容通常需要重新绘制以适应新的尺寸。
  3. 窗口部分被遮挡后又重新显示时: 如果窗口被其他窗口遮挡,然后又重新露出来,被遮挡的部分通常需要重新绘制。
  4. 手动请求重绘: 通过调用 QWidgetupdate()repaint() 方法,可以手动触发重绘事件。

在 Qt 应用程序中,通常通过重写 QWidgetpaintEvent(QPaintEvent *) 方法来处理绘制逻辑。

例如:

class MyWidget : public QWidget {
protected:
  void paintEvent(QPaintEvent *event) override {
    QPainter painter(this);
    // 绘制逻辑
 }
};

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

2 QPainter画家

2.1 QPainter与设置

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

以下是一些基本的用法示例:
初始化 QPainter: 首先,需要一个 QPaintDevice ,比如一个 QWidgetQPixmap ,然后使用它来初始化 QPainter 对象。

//实例化绘图工具
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);     //消除边缘混叠

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

//定义画笔
QPen pen();    			//构造函数
pen.setColor(Qt::blue);	//画笔颜色
pen.setWidth(5);       	//画笔粗细
//pen.setColor(QColor(14,9,234));   //rgb设定颜色
//pen.setStyle(Qt::DashLine);       //设置风格

//定义画刷
painter.setBrush(Qt::yellow); // 设置画刷颜色为黄色

2.2 QPainter常用图形的绘制

绘制文字:

//窗口正中间绘制文字
painter.setPen(pen);
painter.setFont(QFont("Arial", 20));
painter.drawText(rect(), Qt::AlignCenter, "Qt案例");
//任意位置绘文字
painter.setPen(Qt::red);
painter.setFont(QFont("宋体", 15));
painter.drawText(600,550,"自定义位置");

绘制线条:

//画线  绝对坐标画线
painter.setPen(Qt::blue);
painter.drawLine(10,200, 300,20);                   //x,y,x,y
painter.drawLine(QLine(10,300, 400,30));            //x,y,x,y
painter.drawLine(QPoint(10,400),QPoint(300,590));   //P1:x,y P2:x,y

绘制矩形:

//绘制矩形
painter.setPen(Qt::black);
painter.drawRect(QRect(500,30,200,100));    //左上角:x,y, 长 宽

绘制椭圆 / 圆

//画椭圆/圆
painter.setPen(Qt::green);
painter.drawEllipse(QRect(500,30,200,100));    //矩阵区域画椭圆
painter.drawEllipse(QPoint(400,300),200,100);  //椭圆中心 长半轴 短半轴
painter.drawEllipse(rect().center(),200,100);  //椭圆中心 长半轴 短半轴
//画圆
painter.drawEllipse(QPoint(400,500),80, 80);   //圆中心 半径 半径

绘制圆弧:
  绘制由给定矩形 startAngle 和 spanAngle 定义的圆弧。startAngle 和 spanAngle 必须以 1/16 度为单位指定,即一个完整的圆等于5760(16 * 360)。角度的正值表示逆时针方向,负值表示顺时针方向。零度位于 3 点钟位置。

painter.setPen(Qt::red);
QRect rectangle(650, 250, 100, 100);
//度数对应数学的象限度数
int startAngle = 0 * 16;
int spanAngle = 270 * 16;
//矩形区域 起始角度 偏转角度
painter.drawArc(rectangle, startAngle, spanAngle);

绘制扇形:
  绘制由给定矩形 startAngle 和 spanAngle 定义的扇形,并被当前的 brush()填满,方向角度与圆弧规则一致。

//画扇形
//drawPie(int x, int y, int width, int height, int startAngle, int spanAngle)
int startAngle = 0 * 16;
int spanAngle =  120 * 16;
painter.drawPie(QRect(300,200,200,200), startAngle, spanAngle

  结束绘制:完成绘制后, QPainter 对象会在其析构函数中自动结束绘制。请注意, QPainter 的使用依赖于 Qt 的事件循环,因此通常在 QWidget 的 paintEvent 或者类似的事件处理函数中使用它。如果您在 Qt 应用程序中使用 QPainter ,请确保您遵循 Qt 的事件驱动机制。

3 渐变色

3.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 )。

  请注意,当窗口小部件的大小发生变化时,渐变的效果可能也会随之改变,除非你相应地调整渐变的起点和终点坐标或使用其他方法来适应大小变化。

3.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 可以用于填充任何形状,如矩形、椭圆、多边形等。

  • 当绘制较大区域时,可以通过调整渐变的半径和中心点来控制渐变效果的扩展。

  • QRadialGradient 非常适用于创建像按钮、指示灯或其他需要有深度感和立体感的界面元素。

3.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度)通常在三点钟方向。
  • QConicalGradient 非常适合用于创建旋转或动态效果的图形,例如加载指示器、进度条或任何需要圆周颜色变化的场景。

4 模拟雷达扫描器的设计

4.1 坐标转移

  在 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.2 雷达页面的实现

  雷达界面主要绘制黑色背景、多个同心圆、横纵坐标以及采用锥形渐变的扇形区域,及具体相关各部分程序如下所示:

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    //消除边缘混叠
    painter.setRenderHint(QPainter::Antialiasing,true);

    // 把背景色刷成黑色
    QBrush brush(Qt::black);
    painter.setBrush(brush);
    painter.drawRect(rect());

    //设置画笔
    QPen pen(Qt::green,4);
    painter.setPen(pen);

    //坐标转移至正中间
    painter.translate(rect().center());

    //画圆
    painter.setBrush(Qt::NoBrush);
    for(int i = 50; i <= 300; i += 50)
    {
        painter.drawEllipse(QPoint(0,0),i,i);
    }
    //画线 横纵坐标
    painter.drawLine(QPoint(-300,0), QPoint(300,0));
    painter.drawLine(QPoint(0,-300), QPoint(0,300));


    //设置锥形渐变
    QConicalGradient conGradient(0,0,startAngle);
    conGradient.setColorAt(0,QColor(0,255,0,200));
    conGradient.setColorAt(0.1,QColor(0,255,0,100));
    conGradient.setColorAt(0.2,QColor(0,255,0,0));
    conGradient.setColorAt(1,QColor(0,255,0,0));

    //直接用渐变色指定画刷
    painter.setBrush(conGradient);
    painter.setPen(Qt::NoPen);  //去除扇形区域边框

    //画出扇形,启动角度是startAngle,由定时器来修改
    painter.drawPie(QRect(-300,-300,600,600),startAngle*16,spanAngle*16);

}

在这里插入图片描述

4.3 雷达动态扫描的实现

通过定时器改变扇形的起始角度即可实现模拟雷达的扫描功能

//在构造函数中加入以下程序
//实例化定时器及参数设置
timer = new QTimer(this);
timer->setInterval(20); //定时时间
timer->start();

//设置起始角度与偏转角度
startAngle = 0;
spanAngle = 70;

//定时器槽函数
connect(timer,&QTimer::timeout,[=](){
    startAngle += 1;
    if(startAngle >= 360)
        startAngle = 0;
    update();
});

补充:类的定义
在这里插入图片描述

5 综合应用:简易汽车仪表盘的设计

5.1 简易仪表盘的初步设计

  运用上述知识,通过坐标转移,初步绘制底色、,红色渐变的大小圆,通过通过save()方法保存当前的坐标位置。

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);

//底色刷成黑色
painter.setBrush(Qt::black);
painter.drawRect(rect());

//左边转移至正中间
painter.translate(rect().center());

//画红色径向渐变圆
QRadialGradient radialGradient(QPoint(0, 0), 300);      // 中心和半径 (50, 50, 50)
// 设置颜色停靠点
radialGradient.setColorAt(0.0, QColor(255,0,0,50));     // 中心颜色
radialGradient.setColorAt(1.0, QColor(255,0,0,250));    // 外围颜色

// 使用这个渐变创建 QBrush
QBrush brush(radialGradient);
painter.setBrush(brush);
//画大圆
painter.drawEllipse(QPoint(0,0),300,300);
//画小圆
painter.setBrush(Qt::NoBrush);
painter.setPen(QPen(Qt::white,3));
painter.drawEllipse(QPoint(0,0),60,60);

画仪表盘刻度
  通过rotate()实现对坐标轴的旋转来绘制仪表盘的刻度线与数字,保存3点钟方向的坐标系为初始坐标系,将坐标系旋转到起始角度,在x轴末端绘制一小段线段,通过循环每次旋转一定的角度绘制所有的刻度,并绘制相关的刻度。

在这里插入图片描述

//画仪表盘刻度
painter.rotate(135);	//恢复坐标系 3点方向为0度
//起始0码 
painter.drawLine(300-20,0,300-3,0);    //整十码 稍长刻度
painter.setFont(QFont("宋体", 18));
painter.drawText(300-50,12, QString::number(0));

//计算每格的度数
double angle = 270 * 1.0 / 50;	
for(int i = 1; i <= 50; i++)
{
    //算出一个刻度的角度 270度 50份
    painter.rotate(angle);    //坐标轴旋转
    if( i % 10 == 0)	//如果是整十码
    {
        //任意位置绘文字
        painter.setFont(QFont("宋体", 15));
        painter.drawLine(300-20,0,300-3,0);     //整十码 稍长刻度
        //左侧码数 数字摆正
        if(135 + angle * i < 270)
        {
            painter.rotate(180);
            painter.drawText(-300+30,12, QString::number(i));
            painter.rotate(180);
        }
        else
            painter.drawText(300-65,12, QString::number(i));
    }
    else
    {
        painter.drawLine(300-8,0,300-3,0);     //短刻度
    }
}

绘制指针与扇形扫描区域

//画指针 恢复指针到0码方向
painter.restore();  //重置坐标系
painter.save();     //保存当前坐标系
painter.rotate(135 + spanAngle);
painter.drawLine(60,0,300-65,0);

//画扇形
painter.restore();  //重置坐标系
painter.save();     //保存当前坐标系
QRect rect(-300+65,-300+65,600-130,600-130);    //确定矩形
painter.setPen(Qt::NoPen);                      //去边框
painter.setBrush(QColor(255,51,183,200));       //指定画刷颜色
painter.drawPie(rect, -135 * 16, -spanAngle * 16);

仿照雷达的设计,通过定时器扫描指针与扇形

//实例化定时器 并设置相关参数
timer = new QTimer(this);
timer->start(15);	//定时器溢出时间
spanAngle = 0;		//偏转角度
direction = 1;		//方向

connect(timer,&QTimer::timeout,[=]()
{
    if(direction == 1)          //正向
    {
        spanAngle++;
        if(spanAngle >= 273)
            direction = 0;
    }
    else                        //反向
    {
        spanAngle--;
        if(spanAngle <= 0)
            direction = 1;
    }
    update();
});

同时可选择将速度刷新到界面

//写当前速度
painter.restore();  //重置坐标系
painter.setFont(QFont("宋体", 18));
//居中对齐写速度
painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(int(spanAngle/5.4)));

5.2 简易仪表盘的优化与封装

成员变量的初始化及其方法的封装声明

成员变量与方法声明

private:
    Ui::Widget *ui;
    QTimer *timer;      //偏转定时器

    //参数定义
    int startAngle;     //0码的起始角度
    int spanAngle;      //偏转角度
    int direction;      //方向
    int boardSpanAngle; //表盘的跨度
    //计算每一个刻度的角度 240度 60份
    double angle;

    //方法定义
    void initCanvas(QPainter& painter);                     //初始化画布
    void drawCurrentSpeed(QPainter& painter);               //显示当前速度
    void drawScale(QPainter& painter, int radius);          //画仪表盘刻度线
    void drawScaleText(QPainter &painter, int radius);      //画仪表盘刻度数字
    void drawSpeedLine(QPainter &painter, int length);      //画当前速度指针
    void drawSpeedPie(QPainter &painter, int radius);       //画扫描的速度扇形
    void drawRedCircle(QPainter &painter, int radius);      //绘制内部红圈
    void drawBlackCircle(QPainter &painter, int radius);    //绘制内部黑圈
    void drawOutShine(QPainter &painter, int radius);       //绘制外部发光圈
    void drawLogo(QPainter &painter,int radius);            //绘制logo

构造函数初始化成员变量

timer = new QTimer(this);
timer->start(1);
//绑定定时器溢出槽函数
connect(timer, SIGNAL(timeout()), this, SLOT(timeOutHandler()));

startAngle = 150;       //起始需偏转150位置
spanAngle = 0;
direction = 1;
boardSpanAngle = 240;   //仪表盘跨度度数
angle = boardSpanAngle * 1.0 / 60;  //每一小刻度的度数
setFixedSize(800,600);

成员方法的实现

初始化幕布

//初始化画布
void Widget::initCanvas(QPainter &painter)
{
    //边缘细化
    painter.setRenderHint(QPainter::Antialiasing,true);

    //底色刷成黑色
    painter.setBrush(Qt::black);
    painter.drawRect(rect());

    //左边转移至中间位置
    QPoint center(width()/2, height()*0.6);
    painter.translate(center);
}

画仪表盘刻度线

//画仪表盘刻度线
void Widget::drawScale(QPainter &painter, int radius)
{
    //保存3点为x轴的坐标系
    painter.save();
    //初初始化偏转角度
    painter.rotate(startAngle);     //偏转坐标系到150° 0码位置

    //绘制刻度线
    for(int i = 0; i <= 60; i++)
    {
        if( i % 5 == 0){
            painter.setPen(QPen(Qt::white,4));          //设置刻度线粗细
            if(i >= 40 )
                painter.setPen(QPen(Qt::red,4));        //高速红色
            painter.drawLine(radius-20,0,radius-3,0);   //整十码 稍长刻度
        }
        else{
            painter.setPen(QPen(Qt::white,3.5));        //设置刻度线粗细
            if(i >= 40 )
                painter.setPen(QPen(Qt::red,4));        //高速红色
            painter.drawLine(radius-8,0,radius-3,0);    //短刻度
        }
        painter.rotate(angle);    //坐标轴旋转
    }
}

在这里插入图片描述
☆绘制刻度
  通过将坐标平移至对应的各个位置,在矩形框内进行绘制数字,其中转移的横纵坐标根据三角函数进行计算,其中 x = R * cosα, y = R * sinα,而α 则与偏转角度 i * angle 存在关系,210°表示从0刻度到3点钟方向之间的夹角。
在这里插入图片描述在这里插入图片描述
另外可对每个数字进行一定的角度旋转,使得刻度数字与表盘弧度匹配:

painter.rotate(-120 + angle * i);

绘制刻度整体实现

//画仪表盘刻度数字
void Widget::drawScaleText(QPainter &painter, int radius)
{
    //恢复坐标轴
    painter.restore();
    painter.save();             //保存坐标系
    int R = radius-42;          //定义半径

    //设置字体
    painter.setPen(Qt::white);  //设置画笔颜色
    QFont font("Arial",13);     //构造函数 设置字体格式与大小
    font.setBold(true);         //设置粗体
    painter.setFont(QFont("Arial",13));
    //画刻度数字
    for(int i = 0; i <= 60; i++)
    {
        if(i % 5 == 0)
        {
            painter.save();     //保存坐标系
            //1. 算出平移点
            //qCos参数为弧度 通过qDegreesToRadians 度转弧度
            int delx = qCos(qDegreesToRadians(210 - angle * i)) * R;
            int dely = qSin(qDegreesToRadians(210 - angle * i))  * R;
            //2. 平移坐标系
            painter.translate(QPoint(delx, -dely));
            //旋转坐标系
            painter.rotate(-120 + angle * i);

            //3. 绘制文字
            painter.drawText(QRect(-30,-30,60,60), Qt::AlignCenter, QString::number(i*4));

            painter.restore();  //恢复坐标系
        }
    }
}

绘制当前速度指针

//画扫描的速度扇形
void Widget::drawSpeedPie(QPainter &painter, int radius)
{
    //画扇形
    painter.restore();              //重置坐标系
    QRect rect(-radius, -radius, radius * 2, radius * 2);    //确定矩形
    painter.setPen(Qt::NoPen);                              //去边框
    painter.setBrush(QColor(255,0,0,80));               //指定画刷颜色
    painter.drawPie(rect, -startAngle * 16, -spanAngle * 16);
}

绘制扫描的速度扇形

//画扫描的速度扇形
void Widget::drawSpeedPie(QPainter &painter, int radius)
{
    //画扇形
    painter.restore();              //重置坐标系
    QRect rect(-radius, -radius, radius * 2, radius * 2);    //确定矩形
    painter.setPen(Qt::NoPen);                              //去边框
    painter.setBrush(QColor(255,0,0,80));               //指定画刷颜色
    painter.drawPie(rect, -startAngle * 16, -spanAngle * 16);
}

绘制内部渐变红圈

void Widget::drawRedCircle(QPainter &painter, int radius)
{
    QRadialGradient radGradient(0,0,radius);

    radGradient.setColorAt(0,QColor(255,0,0,250));
    radGradient.setColorAt(1,QColor(0,0,0,50));
    painter.setBrush(radGradient);
    painter.setPen(Qt::NoPen);

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

定时器溢出槽函数

//定时器溢出槽函数
void Widget::timeOutHandler()
{
    if(direction == 1)          //正向
    {
        spanAngle++;
        if(spanAngle >= boardSpanAngle + 1)
            direction = 0;
    }
    else                        //反向
    {
        spanAngle--;
        if(spanAngle <= 0)
            direction = 1;
    }
    update();
}

绘制内部黑圈

void Widget::drawBlackCircle(QPainter &painter, int radius)
{
    painter.setBrush(Qt::black);
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(QPoint(0,0),radius,radius);
}

显示当前速度

//显示当前速度
void Widget::drawCurrentSpeed(QPainter &painter)
{
    //设置画笔及字体
    painter.setPen(Qt::white);  //设置画笔颜色
    QFont font("Arial",26);     //字体样式 大小
    font.setBold(true);         //加粗
    painter.setFont(font);      //设置字体

    //居中对齐写速度
    painter.drawText(QRect(-60,-60,120,80),Qt::AlignCenter,QString::number(spanAngle));
    QFont font2("Arial",12);     //字体样式 大小
    font2.setBold(true);         //加粗
    painter.setFont(font2);      //设置字体
    painter.drawText(QRect(-60,-60,120,180),Qt::AlignCenter,"Km/h");
}

绘制外部红色渐变光圈

void Widget::drawOutShine(QPainter &painter, int radius)
{
    //画扇形
    QRect rect(-radius, -radius, radius * 2, radius * 2);    //确定矩形
    painter.setPen(Qt::NoPen);                              //去边框

    QRadialGradient radGradient(0,0,radius);

    radGradient.setColorAt(0,QColor(255,0,0,0));
    radGradient.setColorAt(0.91,QColor(255,0,0,0));
    radGradient.setColorAt(0.96,QColor(255,0,0,120));
    radGradient.setColorAt(1,QColor(255,0,0,255));
    painter.setBrush(radGradient);

    painter.drawPie(rect, -startAngle * 16, -60 * angle * 16);
}

绘制Logo

void Widget::drawLogo(QPainter &painter, int radius)
{
    QRect rect(-100,radius * 0.38, 200, 60);
    painter.drawPixmap(rect,QPixmap(":/icon.png"));
}
  • 26
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会编程的小江江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值