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

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

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.mfbz.cn/a/427811.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

端接电阻没选对,DDR颗粒白费?

高速先生成员--姜杰 端接可以解决很多反射问题&#xff0c;如果还有问题&#xff0c;有没有一种可能是端接电阻阻值没选对&#xff1f; 对于点到点的拓扑&#xff0c;末端并联电阻的阻值比较容易选择&#xff0c;端接电阻阻值R与传输线特征阻抗一样即可。 VTT为1V时&#xff0c…

Linux-查看服务器配置信息

一、查看操作系统 1.1、查看操作系统的版本 命令:cat /etc/redhat-release 1.2、查看系统内核 命令:uname –a 二、查看cpu信息 2.1、所有信息 lscpu [root@tes ~]# lscpu Architecture: x86_64 ##cpu架构 CPU op-mode(s): 32-bit, 64-bit Byte Order:…

大模型日报|今日必读的5篇大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.杨立昆团队提出图像世界模型&#xff1a;在视觉表征学习中学习和利用世界模型 联合嵌入预测架构&#xff08;JEPA&#xff09;通过利用世界模型进行学习&#xff0c;被认为是一种很有前途的自监督方法&#xff0c;…

[环境配置]ssh连接报错“kex_exchange_identification: read: Connection reset by peer”

已经被VScode ssh毒死好几次了&#xff0c;都是执行命令意外中断&#xff0c;然后又VSCode里连不上、本机Terminal也连不上了。。。 重启远程服务器&#xff0c;VSCode可以连上了&#xff0c; 系统ssh还是不行&#xff0c;报错“kex_exchange_identification: read: Connecti…

Linux系统CPU模式部署Qwen1.5-14B

Qwen1.5已适配Ollama。 Ollama 是一个命令行聊天机器人&#xff0c;它使得几乎可以在任何地方使用大型语言模型变得简单。 下载 Ollma 安装文件 访问以下网站&#xff1a;https://ollama.com/download/linux 执行&#xff1a;curl -fsSL https://ollama.com/install.sh | sh…

大地测量学课堂笔记:1、绪论

慕课网址&#xff1a;https://www.icourse163.org/course/WHU-1464124180?fromsearchPage&outVendorzw_mooc_pcssjg_https://www.icourse163.org/course/WHU-1464124180?fromsearchPage&outVendorzw_mooc_pcssjg_ 1. 大地测量学的定义 大地测量学是专门研究精确测量…

MySQL基础-----可视化工具DataGrip安装与使用

目录 前言 安装DataGrip 使用 1.添加数据源 2.展示所有数据库 3. 创建数据库 4.创建表 5.修改表结构 6. 在DataGrip中执行SQL语句 汉化 前言 上一期&#xff0c;我们已经讲解了通过DDL 语句&#xff0c;如何操作数据库、操作表、操作表中的字段&#xff0c;而通过 D…

计算机提示vcruntime140.dll丢失,教你5个方法快速解决dll问题

当计算机系统中无法找到vcruntime140.dll这个特定的动态链接库文件时&#xff0c;可能会引发一系列运行问题&#xff0c;具体表现形式多样且影响范围较广。对于依赖于该文件运行的各类软件应用来说&#xff0c;缺失vcruntime140.dll将直接导致程序无法正常启动或执行&#xff0…

XSS_lab(level6-level10)

level6 仍旧输入:<script>alert(1)</script> script被加了下划线 尝试on事件 也被加了下划线 尝试伪协议:"><a hrefjavascript:alert(1)>1</a>// 还是被加了下划线&#xff0c;那么就要尝试绕过方法了&#xff1a; 我所知的几种绕过方法&a…

ASPICE 4.0 Upgrade Training升版资质更新及升版变化快速解读

ASPICE 4.0 升版变化快速解读 亚远景科技在3月1日举办了ASPICE 4.0 升版变化快速解读培训会&#xff0c;ASPICE首席评估师胡浩在会上进行了精彩分享&#xff0c;部分内容截图&#xff1a; 资料领取请关注我们公众号&#xff1a;研发管理 回复关键词“ASPICE升版变化”即可领取…

牛客练习赛122

D:圆 正着求删除的最小代价不好做&#xff0c;采用逆向思维&#xff0c;求选择一些不相交的线段使得构成一个圆的代价尽量大&#xff0c;最后答案就是所有线段权值之和减去最大代价。 那么如何求这个最大代价呢&#xff1f;显然区间DP 老套路&#xff1a;破环成链&#xff0…

微信小程序中使用特使字体

1、首先下载字体文件 推荐几个常用下载字体的网站 https://font.chinaz.com/zhongwenziti.html https://www.hellofont.cn/ 2、转换字体 使用下面这个网站进行字体转换 https://transfonter.org/ 点击add fonts 按钮进行上传刚刚下载的字体文件选择formats格式&#xff1a;可…

38. 【Linux教程】Linux 修改文件权限

前面小节介绍了用户权限相关的知识&#xff0c;从这一小节开始我们将要开始学习文件权限相关的知识&#xff0c;如何给文件修改权限&#xff0c;之前小节介绍过 ls 命令展示出来的一些文件相关的信息&#xff0c;这里面就有和文件权限相关的信息。 在 Linux 系统中&#xff0c…

Vue3学习记录(三)--- 组合式API之生命周期和模板引用

一、生命周期 1、简介 ​ 生命周期&#xff0c;指的是一个 Vue 实例从创建到销毁的完整阶段&#xff0c;强调的是一个时间段。 ​ 生命周期钩子函数&#xff0c;指的是 Vue 实例提供的内置函数&#xff0c;函数的参数为一个回调函数。这些钩子函数会在实例生命周期的某些固定…

springboot心灵治愈交流平台源码和论文

本论文主要论述了如何使用JAVA语言开发一个心灵治愈交流平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述心灵治愈交流平台的当前背景以及系统开发的目的&a…

Unity UGUI之Slider基本了解

在Unity中&#xff0c;Slider&#xff08;滑动条&#xff09;是一种常用的用户界面控件之一&#xff0c;允许用户通过拖动滑块来选择一个数值。常常应用于调节数值&#xff08;如调节音量、亮度、游戏难度等&#xff09;、设置选项等。 以下是Slider的基本信息和用法: 1、创建…

深入 Starknet 去中心化世界,探秘实用开发利器

Starknet 近期开放空投&#xff0c;面向 130 万地址总量发放超 7 亿枚 Token&#xff0c;让 ECMP 早期贡献者、GitHub 开源开发者、Starknet 用户等各个层面的生态参与者都得以深度参与。 盛宴的背后&#xff0c;是 Starknet 正迎来发展的关键机遇。在今年以太坊坎昆升级的背景…

python最小公倍数 2023年9月青少年电子学会等级考试 中小学生python编程等级考试二级真题答案解析

目录 python最小公倍数 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python最小公倍数 2023年9月 python编程等级考试级编程题 一、题目要求…

【Redis】深入理解 Redis 常用数据类型源码及底层实现(6.详解Set和ZSet数据结构)

本文是深入理解 Redis 常用数据类型源码及底层实现系列的第6篇&#xff5e;前5篇可移步(&#xffe3;∇&#xffe3;)/ 【Redis】深入理解 Redis 常用数据类型源码及底层实现&#xff08;1.结构与源码概述&#xff09;-CSDN博客 【Redis】深入理解 Redis 常用数据类型源码及底…

XSS_lab(level1-level5)

level1 直接输入页面没有发现输入框&#xff0c;观察url发现有传参 尝试修改传参为&#xff1a;<script>alert(1)</script> 过啦&#xff01; level2 页面中有输入框&#xff0c;尝试构建语句&#xff1a;<script>alert(1)</script>,传输后查看源代…