QT圆形进度条(QT桌面项目光照强度检测)

文章目录

  • 前言
  • 一、编程思路
  • 二、核心代码实现
  • 总结


前言

本篇文章我们讲解QT实现圆形进度条,并实现动态的效果。

一、编程思路

实现QT圆形进度条其实是非常简单的,思路就是画两个圆弧。
这里大家就会觉得很奇怪了为什么画两个圆弧就能实现圆形进度条了呢?那么下面我们一个个圆弧来画看看效果。

代码:

    painter.translate(width() / 2, height() / 2);

    QPen pen;
    pen.setWidth(20);//设置笔的大小
    /*设置圆弧连接处为圆形*/
    pen.setJoinStyle(Qt::RoundJoin);
    pen.setCapStyle(Qt::RoundCap);
    pen.setColor(Qt::gray);

    painter.setPen(pen);

    QRect rect(-(height() / 4), -(height() / 4), (height() / 2), (height() / 2));

    painter.drawArc(rect, 0, 360 * 16);/*外部圆弧*/

效果:

我们首先画一个0到360°角的圆弧,并且把笔的颜色设置为灰色,这样的效果看起来就是空心的一个圆环了。这里需要特别注意的就是需要设置一下笔的大小,因为默认笔的大小画出来的圆弧是一根线,这里需要将笔的大小设置的大一点这样看起来才像是一个空心的圆环。

在这里插入图片描述
现在我们来画这个进度条,进度条其实也是画圆弧来实现的,这里根据进度条的百分比来设置进度条的颜色。这个进度条绘制的方法和上面的绘制方法是一样的,上面的圆弧的角度是0到360这样看起来就是一个圆形,那么这里我们绘制这个进度条的时候根据需求来绘制角度就可以了。
通过改变绘制角度来达到进度条的效果。

/*进度条颜色设置(根据百分比设置成不同的颜色)*/
void Widget::ProgressBarColorSet(QPainter& painter)
{
    QPen pen;
    pen.setWidth(20);
    pen.setJoinStyle(Qt::RoundJoin);
    pen.setCapStyle(Qt::RoundCap);


    Light_Intensity = (float)m_endAngle / 360 * 100;
    if(Light_Intensity <= 25)
    {
        pen.setColor(Qt::green);
    }
    else if(Light_Intensity > 25 && Light_Intensity <= 50)
    {
        pen.setColor(Qt::blue);
    }
    else if(Light_Intensity > 50 && Light_Intensity <= 75)
    {
        pen.setColor(Qt::yellow);
    }
    else
    {
        pen.setColor(Qt::red);
    }

    painter.setPen(pen);
}

painter.drawArc(rect, m_startAngle * 16, -m_endAngle * 16);/*内部进度条*/

二、核心代码实现

代码部分主要就是来讲解一下动画的实现,QT中的动画类我们在前面的文章中也讲解到了大家可以去看之前的文章。

主要就是将角度设置为一个属性提供给QPropertyAnimation创建出的对象类修改以达到动画的效果。

修改自定义的endAngle属性来达到修改圆形进度条的进度的效果,并且使用update()函数更新效果。

widget.c

#include "widget.h"
#include <QPainter>
#include <QFont>
#include <QProgressBar>
#include <QRect>
#include <QPalette>
#include <QPushButton>


Widget::Widget(QWidget *parent): QWidget(parent), Light_Intensity(0),
    m_startAngle(90), m_endAngle(0)
{
    /*背景图设置*/
    QPixmap pixmap(":/backgruond.gif");
    QPalette palette;
    palette.setBrush(backgroundRole(), QBrush(pixmap));
    setPalette(palette);
    setAutoFillBackground(true);

    QPushButton* button = new QPushButton(this);
    button->setText("点我");
    connect(button, SIGNAL(clicked()), this, SLOT(clicked()));

    animation = new QPropertyAnimation(this, "endAngle");
    animation->setDuration(500);
    animation->setStartValue(0); // 属性的起始值

    setFixedSize(1024, 600);
}

void Widget::clicked()
{
    animation->setStartValue(m_endAngle); // 属性的起始值
    animation->setEndValue(m_endAngle + 36); // 属性的结束值
    setEndAngle(m_endAngle + 36);

    // 启动动画
    animation->start();
}

void Widget::DrawText(QPainter& painter)
{
    painter.save();

    painter.translate(width() / 2, height() / 2);

    QRect rect2(-(height() / 6), -(height() / 6), (height() / 3), (height() / 3));
    QRect rect1(-(height() / 6), -(height() / 6), (height() / 3), (height() / 6));

    QPen pen;
    pen.setColor(Qt::white);
    painter.setPen(pen);
    QFont font1("微软雅黑", 25);
    painter.setFont(font1);
    painter.drawText(rect1, Qt::AlignCenter, "光照强度");

    QFont font2("微软雅黑", 30);
    painter.setFont(font2);

    painter.drawText(rect2, Qt::AlignCenter, QString::number(Light_Intensity, 'g', 3) + "%");

    painter.restore();
}

/*进度条颜色设置(根据百分比设置成不同的颜色)*/
void Widget::ProgressBarColorSet(QPainter& painter)
{
    QPen pen;
    pen.setWidth(20);
    pen.setJoinStyle(Qt::RoundJoin);
    pen.setCapStyle(Qt::RoundCap);


    Light_Intensity = (float)m_endAngle / 360 * 100;
    if(Light_Intensity <= 25)
    {
        pen.setColor(Qt::green);
    }
    else if(Light_Intensity > 25 && Light_Intensity <= 50)
    {
        pen.setColor(Qt::blue);
    }
    else if(Light_Intensity > 50 && Light_Intensity <= 75)
    {
        pen.setColor(Qt::yellow);
    }
    else
    {
        pen.setColor(Qt::red);
    }

    painter.setPen(pen);
}

void Widget::DrawCirque(QPainter& painter)
{
    painter.save();

    painter.translate(width() / 2, height() / 2);

    QPen pen;
    pen.setWidth(20);//设置笔的大小
    /*设置圆弧连接处为圆形*/
    pen.setJoinStyle(Qt::RoundJoin);
    pen.setCapStyle(Qt::RoundCap);
    pen.setColor(Qt::gray);

    painter.setPen(pen);

    QRect rect(-(height() / 4), -(height() / 4), (height() / 2), (height() / 2));

    painter.drawArc(rect, 0, 360 * 16);/*外部圆弧*/

    ProgressBarColorSet(painter);//设置进度条颜色
    painter.drawArc(rect, m_startAngle * 16, -m_endAngle * 16);/*内部进度条*/

    painter.restore();
}

void Widget::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);//设置抗锯齿

    DrawCirque(painter);//绘制圆环进度条

    DrawText(painter);//绘制文字
}

float Widget::GetLight_Intensity()
{
    return Light_Intensity;
}

Widget::~Widget()
{
}


Q_PROPERTY 是 Qt 中的一个宏,能够帮助开发人员将类的成员变量(或方法)暴露为一个属性( property )。这使得其他开发人员可以通过使用该类的对象来读取或设置这些属性。这些属性可用于界面设计、特定功能或其他目的。

Q_PROPERTY 宏需要几个参数来定义一个属性,包括:属性的返回类型、读取函数、写入函数。

对于 Q_PROPERTY(int endAngle READ endAngle WRITE setEndAngle NOTIFY endAngleChanged) ,它定义了一个名为 endAngle 的整数属性。其他开发人员可以使用 readEndAngle() 和 writeEndAngle() 方法来分别读取和设置此属性,并且 endAngleChanged() 信号将在属性更改时发出通知。此属性是可读取、可写入的并且是整数类型。

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QPen>
#include <QPropertyAnimation>
#include <QDebug>

class Widget : public QWidget
{
    Q_OBJECT
    /*定义一个可读(READ)并且可写(WRITE)的属性,并且可以通过属性名称进行访问*/
    Q_PROPERTY(int endAngle READ endAngle WRITE setEndAngle NOTIFY endAngleChanged)

    float Light_Intensity;//光照强度
    int m_startAngle;
    int m_endAngle;

    QPropertyAnimation* animation;

    void DrawCirque(QPainter& painter);
    void DrawText(QPainter& painter);
    void ProgressBarColorSet(QPainter& painter);

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    float GetLight_Intensity();//获取光照强度

    int endAngle() const
    {
        return m_endAngle;
    }
    void setEndAngle(const int& endAngle)
    {
        m_endAngle = endAngle;
        update();
    }


protected:
    void paintEvent(QPaintEvent* event);

signals:
    void endAngleChanged(int Angle);

protected slots:
    void clicked();
};
#endif // WIDGET_H

总结

掌握好QPainter的实现我们可以做出非常多的好看的项目,希望大家好好的学习QPainter的绘制方法。现在我们的QT桌面项目又更近了一步,大家继续加油!我也会持续为大家写出更多的项目。

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

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

相关文章

轻NAS搭建 - 使用微力同步搭建私人云盘,无需公网IP也能远程访问

文章目录 1.前言2. 微力同步网站搭建2.1 微力同步下载和安装2.2 微力同步网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 私有云盘作为云存储概念的延伸&#xff0c;虽然谈不上多么新颖&#xff0c;但是其…

华为OD机试之不含101的整数(Java源码)

不含101的数 题目描述 小明在学习二进制时&#xff0c;发现了一类不含 101的数&#xff0c;也就是&#xff1a; 将数字用二进制表示&#xff0c;不能出现 101 。 现在给定一个整数区间 [l,r] &#xff0c;请问这个区间包含了多少个二进制不含 101 的整数&#xff1f; 输入描述…

2023全球最佳医院榜单及简要介绍

作为医学类的访问学者、博士后及联合培养博士们&#xff0c;都希望到世界知名医院进行临床研修交流及科研学习。2023 年世界最佳医院排行榜的发布为申请者提供了目标平台&#xff0c;现知识人网小编整理刊出。 近期&#xff0c;《新闻周刊》和全球数据公司 Statista 推出了2023…

Vue之MVVM模型

文章目录 前言一、简说MVVM模型二、走进MVVM总结 前言 Vue的创建者在创建Vue时没有完全遵守MVVM&#xff08;一种软件架构模式&#xff09;&#xff0c;但是Vue的设计受到了他它的启发。这也是为什么经常用vm&#xff08;ViewModel的缩写&#xff09;这个变量名表示Vue实例。 …

操作系统第三章——内存管理(中)

九月重楼二两&#xff0c;冬至蝉蜕一钱&#xff0c;煎入隔年雪煮沸&#xff0c;可治人间相思苦疾&#xff0c; 可是&#xff0c;重楼七叶一花&#xff0c;冬日何来蝉蜕&#xff0c;原是相思无解 殊不知 夏枯即为九叶重楼&#xff0c;掘地三尺寒蝉现&#xff0c;除夕子时雪&…

non-protected broadcast场景分析及解决

non-protected broadcast场景分析及解决 在两个app之间互相送消息使用BroadcastReceiver&#xff0c;有时在运行过程中在logcat工具中会发现大片的飘红消息。 要消除这些错误信息&#xff0c;需要在广播的 Sender 和 Receiver 做部分的修改。 错误信息分析 由于 发送端 的 M…

`JOB`的正确打开方式

文章目录 JOB的正确打开方式 简介工作原理使用场景使用方式注意事项启动JOB失败的情况JOB正确打开方式错误方式正确方式进阶方式终极方式 总结 JOB的正确打开方式 最近有一些小伙伴在使用JOB时&#xff0c;由于使用不当&#xff0c;引起一些问题。例如把license占满&#xff0c…

操作系统第四章——文件管理(下)

竹本无心&#xff0c;却节外生枝&#xff0c;藕却有孔&#xff0c;但出淤泥而不染&#xff0c;人生如梦&#xff0c;却却不随人愿&#xff0c;万般皆是命&#xff0c;半点不由人 文章目录 4.1.5 逻辑结构VS物理结构4.1.6 文件的基本操作知识总览创建文件删除文件打开文件关闭文…

【弹性分布式EMA】在智能电网中DoS攻击和虚假数据注入攻击(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

GPC_APDU_Transport_over_SPI-I2C_v1.0_PublicRelease

GPC_APDU_Transport_over_SPI-I2C_v1.0_PublicRelease.pdf 目录 1 简介 越来越多的设备&#xff0c;如移动设备、可穿戴设备或其他 IoT&#xff08;物联网&#xff09;设备现在正在使用焊接安全元件 (SE)。 这产生了支持 SPI 或 I2C 等物理接口的新需求&#xff0c;以代替以前…

Java 反序列化漏洞

反序列化漏洞是指程序在反序列化期间&#xff0c;通过特殊的调用链引发的一系列安全问题。编程语言中只要存在序列化&#xff0c;反序列化功能就可能存在反序列化的安全问题。这里只针对Java和PHP进行讨论。 序列化漏洞概述 序列化的存在主要是为了存储和传输&#xff0c;将这…

如何设置工业设备的振动监测阈值

工业设备的振动阈值设置是确保设备正常运行和及时维护的关键步骤。本文将介绍一些常见的方法和策略&#xff0c;帮助您正确设置工业设备的振动阈值。 1. ISO 10816 振动烈度表格&#xff1a; ISO 10816 是一项国际标准&#xff0c;提供了设备振动水平的参考值。该标准将设备按…

【移动计算技术(Android)】期末复习

目录 选择题 选择题知识点汇总 Activity Intent Broadcast BroadcastReceiver 如何自定义Receiver 如何注册接收器 Service SharedPreferences 三种访问模式 如何创建 如何存储/修改 如何读取 内部存储 openFileOutput openFileInput SD卡 资源文件 SQLite…

Java学习路线(13)——Collection集合类:List集合与Set集合

一、集合类体系结构 二、部分Collection类型对象 Collection集合特点 List系列集合是有序、可重复、有索引。 ArrayList&#xff1a;有序、可重复、有索引LinkedList&#xff1a;有序、可重复、有索引 Set系列集合是无序、不重复、无索引。 HashSet&#xff1a;无序、不重复…

下载YouTube视频的一种方法

文章目录 工具名称下载方法使用方法1.只下载音频2.下载音频转换成mp3&#xff08;加上-x –audio-format参数&#xff09;3.下载视频&#xff08;带音频&#xff09;ID&#xff1a;22 | EXT&#xff1a;mp4 | 1280*720 下载的数据集&#xff1a;YouCook2 工具名称 yt-dlp 下载…

ajax使用

说明&#xff1a;ajax是一门异步处理请求的技术&#xff1b;可以实现不重新加载整个页面的情况下&#xff0c;访问后台后服务&#xff1b;比如百度搜索引擎&#xff0c;输入关键字后&#xff0c;下面会实时出现待选项&#xff0c;这就是一种异步处理请求的技术。 原生Ajax 原…

chatgpt赋能python:Python中未定义变量的默认值

Python中未定义变量的默认值 在Python编程中&#xff0c;有时候我们会使用未经定义的变量。如果这些变量没有被定义&#xff0c;那么它们将没有任何值。在这篇文章中&#xff0c;我们将讨论Python中未定义变量默认值的问题&#xff0c;并深入研究为什么这些默认值如此重要。 …

如何保证三个线程按顺序执行?不会我教你

&#x1f468;‍&#x1f393;作者&#xff1a;bug菌 ✏️博客&#xff1a;CSDN、掘金、infoQ、51CTO等 &#x1f389;简介&#xff1a;CSDN|阿里云|华为云|51CTO等社区博客专家&#xff0c;历届博客之星Top30&#xff0c;掘金年度人气作者Top40&#xff0c;51CTO年度博主Top12…

linux内核内存管理slab

一、概述 linux内存管理核心是伙伴系统&#xff0c;slab&#xff0c;slub&#xff0c;slob是基于伙伴系统之上提供api&#xff0c;用于内核内存分配释放管理&#xff0c;适用于小内存&#xff08;小于&#xff11;页&#xff09;分配与释放&#xff0c;当然大于&#xff11;页…

基于html+css的图展示99

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…