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

news2024/9/21 19:03:30

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

ui

 mainwindow.h

#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

#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

#include "mainwindow.h"

#include <QApplication>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1484519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式中汇编语言的基本实现

大家好&#xff0c;今天给大家分享&#xff0c;GNU汇编的语法。 第一&#xff1a;汇编简介 GNU 汇编语法适用于所有的架构&#xff0c;并不是 ARM 独享的&#xff0c;GNU 汇编由一系列的语句组成&#xff0c; 每行一条语句&#xff0c;每条语句有三个可选部分&#xff0c;如下…

java List.forEach 引发的生产投诉

代码运行时直接抛异常报错&#xff0c;这个算是不幸中的万幸&#xff0c;至少可以及时发现并去解决代码运行不报错&#xff0c;但是业务逻辑莫名其妙的出现各种奇怪问题&#xff0c;这种就比较悲剧了&#xff0c;因为这个问题稍不留神的话&#xff0c;可能就会给后续业务埋下隐…

【C语言】熟悉文件顺序读写函数

前言 本篇详细介绍了 文件顺序读写常用函数&#xff0c;快来看看吧~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 ​编辑 文件顺序读写函数 fgetc函数 示例 fputc函数 逐个字符写入 写入26个字母 文…

数学建模函数插值与拟合

1.脑图 2.介绍 我们自己找到的函数&#xff0c;在已知点处的函数值和要求的函数在这些点处的函数值相等&#xff0c;这个函数 就叫做未知函数的插值函数&#xff1b; 多项式函数构成的插值函数的集合叫做函数类&#xff1b; 3.拉格朗日插值法 基函数的求法和插值函数的构造…

使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

目录 0.课程大纲1.为什么要使用QEMU学习嵌入式QEMU简介使用QEMU可以做哪些事情?当前嵌入式行业现状如何适应这种变化使用QEMU学习嵌入式有哪些好处?驱动开发技能为什么要学习Linux 2.搭建嵌入式开发基本环境2.1.安装u-boot-tools2.2.安装交叉编译工具什么是ABI和EABI 3.QEMU安…

MySQL:开始深入其数据(一)DML

在上一章初识MySQL了解了如何定义数据库和数据表&#xff08;DDL&#xff09;&#xff0c;接下来我们开始开始深入其数据,对其数据进行访问&#xff08;DAL&#xff09;、查询DQL&#xff08;&#xff09;和操作(DML)等。 通过DML语句操作管理数据库数据 DML (数据操作语言) …

第17章-文件传输协议

1. 概述 2. FTP协议 2.1 定义 2.2 端口 2.3 数据传输方式 2.4 文件传输模式 3. TFTP协议 3.1 定义&#xff1a; 4. 常用命令 1. 概述 场景&#xff1a;远端主机和本地服务器 2. FTP协议 2.1 定义 FTP(File Transfer Protocol)&#xff1a;文件传输协议&#xff1b;…

DataX及Datax-web杂记

&#x1f47d;个人博客&#xff1a;https://everspring.github.io/ &#x1f47d;公众号&#xff1a;爱历史的IT男 一. DataX调试 DataX之前调试不是很方便&#xff0c;要打包后才能调试。23年7月后一位叫"FuYouJ "的开源者提交了datax-example模块&#xff0c;就方…

GO-接口

1. 接口 在Go语言中接口&#xff08;interface&#xff09;是一种类型&#xff0c;一种抽象的类型。 interface是一组method的集合&#xff0c;接口做的事情就像是定义一个协议&#xff08;规则&#xff09;&#xff0c;只要一台机器有洗衣服和甩干的功能&#xff0c;我就称它…

13. Springboot集成Protobuf

目录 1、前言 2、Protobuf简介 2.1、核心思想 2.2、Protobuf是如何工作的&#xff1f; 2.3、如何使用 Protoc 生成代码&#xff1f; 3、Springboot集成 3.1、引入依赖 3.2、定义Proto文件 3.3、Protobuf生成Java代码 3.4、配置Protobuf的序列化和反序列化 3.5、定义…

事件循环相关知识

事件循环 浏览器的进程模型 何为进程 程序运行需要有专属的内存空间&#xff0c;可以吧这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信也需要双方同意 何为线程 有了进程就可以运行代码 运行代码的人称为线程 一…

RISC-V特权架构 - 特权模式与指令

RV32/64 特权架构 - 特权模式与指令 1 特权模式2 特权指令2.1 mret&#xff08;从机器模式返回到先前的模式&#xff09;2.2 sret&#xff08;从监管模式返回到先前的模式&#xff09;2.3 wfi&#xff08;等待中断&#xff09;2.4 sfence.vma&#xff08;内存屏障&#xff09; …

beets,一个有趣的 Python 音乐信息管理工具!

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站AI学习网站。 目录 前言 什么是Beet库&#xff1f; 安装Beet库 使用Beet库 Beet库的功能特性 1. 多种音乐格式支持 2. 自动标签识…

Golang embed 库全面解析:从基础到高级应用

Golang embed 库全面解析&#xff1a;从基础到高级应用 引言Golang的 embed&#xff1a;简化资源管理提升可移植性与便利性适用场景的拓展 embed 库的基本概念embed 库的工作原理使用 embed 的基本语法访问嵌入资源的方法embed 的限制 如何使用 embed嵌入单个文件嵌入整个目录结…

JMeter实现接口自动化测试

一、JMETER的环境搭建 参考&#xff1a;https://www.cnblogs.com/qmfsun/p/4902534.html 二、JMETER的汉化 临时汉化方法&#xff1a;打开jmeter&#xff0c;options-->choose language-->选择语言 可以根据自己的需要选择简体中文或者繁体中文&#xff0c;如图&#xf…

力扣180 连续出现的数字

如何有效地识别在数据库中至少连续出现三次的数字&#xff1f; 目录 题目描述 解题思路 完整代码 进一步探索 题目描述 表&#xff1a;Logs ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varch…

13 双口 RAM IP 核

双口 RAM IP 核简介 双口 RAM IP 核有两个端口&#xff0c;它又分为伪双端口 RAM 和真双端口 RAM&#xff0c;伪双端口 RAM 一个端口只能读&#xff0c;另一个端口只能 写&#xff0c;真双端口 RAM 两个端口都可以进行读写操作。同时对存储器进行读写操作时就会用到双端口 RAM…

1、swagger knife4j 3.0.3 集成 springboot

这里写目录标题 一、项目版本二、增加 knife4j maven 依赖三、增加项目配置类四、配置文件增加登录密码五 、访问文档地址 一、项目版本 springboot &#xff1a;2.6.7 swagger&#xff1a;knife4j-spring-boot-starter &#xff1a;3.3.0 二、增加 knife4j maven 依赖 <…

Linux系统源代码数据防泄密加密软件

数据防泄密系统 是一套从源头上保障数据安全和使用安全的软件系统。包含了文件透明加解密、内部文件流转功能、密级管控、离线管理、文件外发管理、灵活的审批流程、工作模式切换、服务器白名单等功能。从根本上严防信息外泄&#xff0c;保障信息安全。 www.weaem.com 功能介绍…

【k8s管理--集群日志管理elk】

1、ELKF日志部署框架 使用docker部署的k8s集群所有的容器日志统一都在目录&#xff1a;/var/log/containers/1、filebeat是一个轻量级的日志手机工具&#xff0c;主要功能是收集日志2、logstash通可以收集日志&#xff0c;也可以进行数据清洗&#xff0c;但是一般不用logstash来…