Qt writes custom controls-arc progress bar

I. Introduction

Nowadays, web-based chart frameworks are very popular. The domestic representative is echart. I have used it several times. I can describe it in three words: it is very powerful and easy to use. It is open source and free. Don’t be too happy to use it. , the various built-in charts and dashboards are very rich, and the presentation forms are also very diverse.
The arc progress bar to be written this time is a reference to an arc progress bar in echart. The main structure is a circle of rounded progress on the periphery, with a title and corresponding progress percentage in the middle, and the starting angle and end of the progress bar. The angle can be adjusted by itself, so that the opening of the progress bar can be anywhere on the left, right, top, bottom, etc., by adjusting the angle. The core of drawing is the drawArc function.

2. Functions implemented

  • 1: The range value can be set, and negative values ​​are supported
  • 2: The accuracy can be set, with a maximum of 3 decimal places supported.
  • 3: Arc width can be set
  • 4: The start rotation angle/end rotation angle can be set
  • 5: The title of the dashboard can be set
  • 6: Background color/progress color/value color/text color can be set
  • 7: Adaptive form stretching, automatic text scaling
  • 8: You can freely expand various gradient colors
  • 9: The percentage mode can be set to automatically convert the calculated value into a percentage.

3. Effect drawing

4. Header file code

#ifndef PROGRESSARC_H
#define PROGRESSARC_H

/**
 * 百分比仪表盘控件 作者:feiyangqingyun(QQ:517216493) 2018-8-30
 * 1:可设置范围值,支持负数值
 * 2:可设置精确度,最大支持小数点后3位
 * 3:可设置圆弧宽度
 * 4:可设置开始旋转角度/结束旋转角度
 * 5:可设置仪表盘的标题
 * 6:可设置背景颜色/进度颜色/值颜色/文字颜色
 * 7:自适应窗体拉伸,文字自动缩放
 * 8:可自由拓展各种渐变色
 * 9:可设置百分比模式,自动计算值换算成百分比
 */

#include <QWidget>

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT ProgressArc : public QWidget
#else
class ProgressArc : public QWidget
#endif

{
    Q_OBJECT
    Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
    Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue)
    Q_PROPERTY(double value READ getValue WRITE setValue)
    Q_PROPERTY(int precision READ getPrecision WRITE setPrecision)

    Q_PROPERTY(int startAngle READ getStartAngle WRITE setStartAngle)
    Q_PROPERTY(int endAngle READ getEndAngle WRITE setEndAngle)

    Q_PROPERTY(QColor arcColor READ getArcColor WRITE setArcColor)
    Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
    Q_PROPERTY(QColor titleColor READ getTitleColor WRITE setTitleColor)
    Q_PROPERTY(QColor baseColor READ getBaseColor WRITE setBaseColor)
    Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)

    Q_PROPERTY(bool percent READ getPercent WRITE setPercent)
    Q_PROPERTY(int arcWidth READ getArcWidth WRITE setArcWidth)
    Q_PROPERTY(QString title READ getTitle WRITE setTitle)

public:
    explicit ProgressArc(QWidget *parent = 0);
    ~ProgressArc();

protected:
    void paintEvent(QPaintEvent *);
    void drawArc(QPainter *painter);
    void drawValue(QPainter *painter);
    void drawTitle(QPainter *painter);

private:
    double minValue;                //最小值
    double maxValue;                //最大值
    double value;                   //目标值
    int precision;                  //精确度,小数点后几位

    int startAngle;                 //开始旋转角度
    int endAngle;                   //结束旋转角度

    QColor arcColor;                //圆弧颜色
    QColor textColor;               //文字颜色
    QColor titleColor;              //标题颜色
    QColor baseColor;               //基准颜色
    QColor bgColor;                 //背景颜色

    bool percent;                   //百分比模式
    int arcWidth;                   //圆弧宽度
    QString title;                  //标题

public:
    double getMinValue()            const;
    double getMaxValue()            const;
    double getValue()               const;
    int getPrecision()              const;

    int getStartAngle()             const;
    int getEndAngle()               const;

    QColor getArcColor()            const;
    QColor getTextColor()           const;
    QColor getTitleColor()          const;
    QColor getBaseColor()           const;
    QColor getBgColor()             const;

    bool getPercent()               const;
    int getArcWidth()               const;
    QString getTitle()              const;

    QSize sizeHint()                const;
    QSize minimumSizeHint()         const;

public Q_SLOTS:
    //设置范围值
    void setRange(double minValue, double maxValue);
    void setRange(int minValue, int maxValue);

    //设置最大最小值
    void setMinValue(double minValue);
    void setMaxValue(double maxValue);

    //设置目标值
    void setValue(double value);
    void setValue(int value);

    //设置精确度
    void setPrecision(int precision);

    //设置开始旋转角度
    void setStartAngle(int startAngle);
    //设置结束旋转角度
    void setEndAngle(int endAngle);

    //设置圆弧颜色
    void setArcColor(const QColor &arcColor);
    //设置文本颜色
    void setTextColor(const QColor &textColor);
    //设置标题颜色
    void setTitleColor(const QColor &titleColor);
    //设置基准颜色
    void setBaseColor(const QColor &baseColor);
    //设置背景颜色
    void setBgColor(const QColor &bgColor);

    //设置百分比模式
    void setPercent(bool percent);
    //设置圆弧宽度
    void setArcWidth(int arcWidth);
    //设置标题
    void setTitle(const QString &title);

Q_SIGNALS:
    void valueChanged(int value);
};

#endif // PROGRESSARC_H


As a benefit for this article, you can receive a Qt development learning package and technical videos for free, including (C++ language basics, introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project practice , QT embedded development, Quick module, etc.) ↓↓↓↓↓↓See below↓↓Click at the bottom of the article to receive the fee↓↓

5. Core code

void ProgressArc::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //绘制背景
    if (bgColor != Qt::transparent) {
        painter.setPen(Qt::NoPen);
        painter.fillRect(this->rect(), bgColor);
    }

    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);

    //绘制圆弧
    drawArc(&painter);
    //绘制当前值
    drawValue(&painter);
    //绘制标题
    drawTitle(&painter);
}

void ProgressArc::drawArc(QPainter *painter)
{
    int radius = 99 - arcWidth;
    painter->save();
    painter->setBrush(Qt::NoBrush);

    QPen pen;
    pen.setWidthF(arcWidth);
    pen.setCapStyle(Qt::RoundCap);

    //计算总范围角度,当前值范围角度,剩余值范围角度
    double angleAll = 360.0 - startAngle - endAngle;
    double angleCurrent = angleAll * ((value - minValue) / (maxValue - minValue));
    double angleOther = angleAll - angleCurrent;
    QRectF rect = QRectF(-radius, -radius, radius * 2, radius * 2);

    //绘制圆弧背景
    pen.setColor(baseColor);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleCurrent - angleOther) * 16, angleOther * 16);

    //绘制圆弧进度
    pen.setColor(arcColor);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleCurrent) * 16, angleCurrent * 16);

    painter->restore();
}

void ProgressArc::drawValue(QPainter *painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(textColor);

    QFont font;
    font.setPixelSize(40);
    painter->setFont(font);
    
    QString strValue;
    if (percent) {
        double temp = value / (maxValue - minValue) * 100;
        strValue = QString("%1%").arg(temp, 0, 'f', precision);
    } else {
        strValue = QString("%1").arg((double)value, 0, 'f', precision);
    }

	QRectF textRect(-radius, 0, radius * 2, radius / 3);
    painter->drawText(textRect, Qt::AlignCenter, strValue);

    painter->restore();
}

void ProgressArc::drawTitle(QPainter *painter)
{
    double radius = 100;
    painter->save();
    painter->setPen(titleColor);

    QFont font;
    font.setPixelSize(25);
    painter->setFont(font);

    QRectF textRect(-radius, -radius / 2.5, radius * 2, radius / 3);
    painter->drawText(textRect, Qt::AlignCenter, title);

    painter->restore();
}

6. Control introduction

  1. More than 160 exquisite controls, covering various dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlight buttons, sliding selectors, lunar calendar, etc. Far exceeds the number of controls integrated by qwt.
  2. Each class can be independently formed into a separate control, with zero coupling. Each control has a header file and an implementation file, and does not rely on other files. It is convenient for a single control to be integrated into the project in the form of source code, with less code. The control classes of qwt are interlocking and highly coupled. If you want to use one of the controls, you must include all the code.
  3. All written in pure Qt, drawn by QWidget+QPainter, supports any Qt version from Qt4.6 to Qt5.13, supports compilers such as mingw, msvc, gcc, etc., and supports any operating system such as windows+linux+mac+embedded linux, etc., without garbled code , can be directly integrated into Qt Creator and used like the built-in controls. Most effects only need to set a few properties, which is extremely convenient.
  4. Each control has a corresponding separate DEMO containing the source code of the control for easy reference and use. It also provides an integrated DEMO used by all controls.
  5. The source code of each control has detailed Chinese comments and is written in accordance with unified design specifications, making it easy to learn how to write custom controls.
  6. The default color matching of each control and the color matching corresponding to the demo are very exquisite.
  7. More than 130 visible controls and 6 invisible controls.
  8. Some controls provide multiple style choices and multiple indicator style choices.
  9. All controls adapt to form stretch changes.
  10. Integrated custom control attribute designer, supports drag and drop design, WYSIWYG, supports import and export of xml format.
  11. Comes with activex control demo, all controls can be run directly in the IE browser.
  12. Integrate fontawesome graphic fonts + hundreds of graphic fonts collected by Alibaba iconfont, and enjoy the fun brought by graphic fonts.
  13. All controls finally generate a dynamic library file (dll or so, etc.), which can be directly integrated into qtcreator for drag and drop design.
  14. There is already a qml version, and a pyqt version will be considered later if there is great demand from users.
  15. The custom control plug-in is open to dynamic library use (free forever), without any backdoors or restrictions, so please feel free to use it.
  16. Currently, 32 versions of dll have been provided, among which the version qt_5_7_0_mingw530_32 will always be guaranteed to be the latest and complete.
  17. Controls are added and improved from time to time, and the SDK is updated from time to time. Suggestions are welcome, thank you!
  18. For introductory Qt books, we recommend Huo Yafei's "Quick Start with Qt Creator" and "Introduction to Qt5 Programming". For advanced Qt books, we recommend the official "C++ GUI Qt4 Programming".
  19. I highly recommend the series of self-cultivation and planning books for programmers, "The Big Talk Programmer", "Programmer's Growth Course", and "The Worry-Relieving Programmer", which will benefit you a lot and will last a lifetime!
  20. SDK address: https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk

Original link: cnblogs.com/feiyangqingyun/p/11684893.html

Guess you like

Origin blog.csdn.net/hw5230/article/details/132782160