QT circular progress bar (QT desktop project light intensity detection)

Article directory

  • foreword
  • 1. Programming ideas
  • 2. Core code implementation
  • Summarize

Foreword

In this article, we explain how QT implements a circular progress bar and achieves dynamic effects.

1. Programming ideas

It is actually very simple to realize the QT circular progress bar. The idea is to draw two arcs.
Everyone will find it very strange here. Why can a circular progress bar be realized by drawing two arcs? Then let’s draw the arcs one by one to see the effect.

code:

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

    QPen pen;
    pen.setWidth(20);//Set the size of the pen
    /*Set the arc connection to a circle*/
    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);/*outer arc*/

Effect:

We first draw an arc with an angle of 0 to 360°, and set the pen color to gray, so that the effect looks like a hollow ring. What needs special attention here is the need to set the size of the pen, because the arc drawn by the default pen size is a line, here you need to set the size of the pen a little larger so that it looks like a hollow ring.


Now let’s draw the progress bar. The progress bar is actually realized by drawing an arc. Here, the color of the progress bar is set according to the percentage of the progress bar. The drawing method of this progress bar is the same as the drawing method above. The angle of the above arc is 0 to 360, so it looks like a circle. Then when we draw this progress bar, we can draw the angle according to the requirement. .
The effect of the progress bar is achieved by changing the drawing angle.

/*Progress bar color setting (set to different colors according to the percentage)*/
void Widget::ProgressBarColorSet(QPainter & amp; 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 & amp; & amp; Light_Intensity <= 50)
    {<!-- -->
        pen.setColor(Qt::blue);
    }
    else if(Light_Intensity > 50 & amp; & amp; Light_Intensity <= 75)
    {<!-- -->
        pen.setColor(Qt::yellow);
    }
    else
    {<!-- -->
        pen.setColor(Qt::red);
    }

    painter.setPen(pen);
}

painter.drawArc(rect, m_startAngle * 16, -m_endAngle * 16); /* internal progress bar */

2. Core code implementation

The code part is mainly to explain the implementation of animation. We also explained the animation class in QT in the previous article. You can read the previous article.

The main thing is to set the angle as a property to modify the object class created by QPropertyAnimation to achieve the effect of animation.

Modify the custom endAngle attribute to achieve the effect of modifying the progress of the circular progress bar, and use the update() function to update the effect.

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)
{<!-- -->
    /*background image setting*/
    QPixmap pixmap(":/backgruond.gif");
    QPalette palette;
    palette.setBrush(backgroundRole(), QBrush(pixmap));
    setPalette(palette);
    setAutoFillBackground(true);

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

    animation = new QPropertyAnimation(this, "endAngle");
    animation->setDuration(500);
    animation->setStartValue(0); // The starting value of the property

    setFixedSize(1024, 600);
}

void Widget::clicked()
{<!-- -->
    animation->setStartValue(m_endAngle); // The starting value of the attribute
    animation->setEndValue(m_endAngle + 36); // The end value of the attribute
    setEndAngle(m_endAngle + 36);

    // start the animation
    animation->start();
}

void Widget::DrawText(QPainter & amp; 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("Microsoft Yahei", 25);
    painter. setFont(font1);
    painter.drawText(rect1, Qt::AlignCenter, "Light intensity");

    QFont font2("Microsoft Yahei", 30);
    painter. setFont(font2);

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

    painter. restore();
}

/*Progress bar color setting (set to different colors according to the percentage)*/
void Widget::ProgressBarColorSet(QPainter & amp; 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 & amp; & amp; Light_Intensity <= 50)
    {<!-- -->
        pen.setColor(Qt::blue);
    }
    else if(Light_Intensity > 50 & amp; & amp; Light_Intensity <= 75)
    {<!-- -->
        pen.setColor(Qt::yellow);
    }
    else
    {<!-- -->
        pen.setColor(Qt::red);
    }

    painter.setPen(pen);
}

void Widget::DrawCirque(QPainter & amp; painter)
{<!-- -->
    painter. save();

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

    QPen pen;
    pen.setWidth(20);//Set the size of the pen
    /*Set the arc connection to a circle*/
    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);/*outer arc*/

    ProgressBarColorSet(painter);//Set the progress bar color
    painter.drawArc(rect, m_startAngle * 16, -m_endAngle * 16); /* internal progress bar */

    painter. restore();
}

void Widget::paintEvent(QPaintEvent* event)
{<!-- -->
    Q_UNUSED(event);

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

    DrawCirque(painter);//Draw a circular progress bar

    DrawText(painter);//draw text
}

float Widget::GetLight_Intensity()
{<!-- -->
    return Light_Intensity;
}

Widget::~Widget()
{<!-- -->
}


Q_PROPERTY is a macro in Qt that can help developers expose class member variables (or methods) as a property (property). This allows other developers to read or set these properties by using objects of this class. These properties may be used for interface design, specific functionality, or other purposes.

The Q_PROPERTY macro requires several parameters to define a property, including: the return type of the property, the read function, and the write function.

For Q_PROPERTY(int endAngle READ endAngle WRITE setEndAngle NOTIFY endAngleChanged) , it defines an integer property named endAngle. Other developers can use the readEndAngle() and writeEndAngle() methods to read and set this property respectively, and the endAngleChanged() signal will notify when the property changes. This property is readable, writable and of type integer.

widget.h

#ifndef WIDGET_H
#define WIDGET_H

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

class Widget : public QWidget
{<!-- -->
    Q_OBJECT
    /*Define a readable (READ) and writable (WRITE) attribute, and can be accessed through the attribute name*/
    Q_PROPERTY(int endAngle READ endAngle WRITE setEndAngle NOTIFY endAngleChanged)

    float Light_Intensity;//light intensity
    int m_startAngle;
    int m_endAngle;

    QPropertyAnimation* animation;

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

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    float GetLight_Intensity();//Get light intensity

    int endAngle() const
    {<!-- -->
        return m_endAngle;
    }
    void setEndAngle(const int & amp; endAngle)
    {<!-- -->
        m_endAngle = endAngle;
        update();
    }


protected:
    void paintEvent(QPaintEvent* event);

signals:
    void endAngleChanged(int Angle);

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

Summary

We can make a lot of good-looking projects by mastering the implementation of QPainter. I hope you can learn the drawing method of QPainter well. Now our QT desktop project is one step closer, everyone continue to work hard! I will continue to write more projects for you.