Qt Writing Custom Control 66-Halo Clock

I. Preface

In the last article, I wrote a halo calendar with high imitation of WIN10 system, this time to draw a halo clock, which is also the effect seen on some webpages. Time and seconds are drawn in the form of a progress bar, and the progress bar has halo effect. The date and time text in the middle is also halo effect. The whole looks a bit sci-fi. This control has no technology. Difficulty, if there is any difficulty, is how to produce this halo effect. When using painter to draw, brush can be set. Brush can be a variety of gradient effects. This is very powerful. There are linear gradient, circular gradient and conical gradient. These three gradients are used well, and all kinds of effects should be handy. In order to produce halo effect, it is necessary to use circular gradient and set transparency value to deal with different positions in circular gradient. Time-seconds corresponding progress can be calculated automatically. This is not difficult. For example, directly using QTime can obtain the corresponding time-seconds, then dividing clock and minute by 60 seconds and dividing seconds by 1000 to obtain the corresponding progress. QPainterPath's addText is used to draw halo text.

II. Functions of Realization

  • 1: Arc radius width can be set
  • 2: Halo width can be set
  • 3: Halo color can be set
  • 4: Text color can be set
  • 5: Using animation mechanism to smooth the time of progress display


Header file code


 * Author of Halo Clock Control: Yutian Ge (QQ:3246214072):feiyangqingyun(QQ:517216493) 2019-10-07
 * 1:Arc radius width can be set
 * 2:Deployable halo width
 * 3:Settable halo color
 * 4:Text color can be set
 * 5:Using animation mechanism to smooth progress display time

#include <QWidget>

#ifdef quc
#include <QtDesigner/QDesignerExportWidget>
#include <QtUiPlugin/QDesignerExportWidget>

class QDESIGNER_WIDGET_EXPORT ShadowClock : public QWidget
class ShadowClock : public QWidget

    Q_PROPERTY(int radiusWidth READ getRadiusWidth WRITE setRadiusWidth)
    Q_PROPERTY(int shadowWidth READ getShadowWidth WRITE setShadowWidth)

    Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
    Q_PROPERTY(QColor shadowColor READ getShadowColor WRITE setShadowColor)

    explicit ShadowClock(QWidget *parent = 0);

    void paintEvent(QPaintEvent *);
    void drawArc(QPainter *painter, int radius, qreal angle);
    void drawText(QPainter *painter);

    int radiusWidth;            //Radius width
    int shadowWidth;            //Halo width

    QColor textColor;           //text color
    QColor shadowColor;         //Halo Color

    int getRadiusWidth()        const;
    int getShadowWidth()        const;

    QColor getTextColor()       const;
    QColor getShadowColor()     const;

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

public Q_SLOTS:
    //Set Radius Width + Halo Width
    void setRadiusWidth(int radiusWidth);
    void setShadowWidth(int shadowWidth);

    //Set text color + halo color
    void setTextColor(const QColor &textColor);
    void setShadowColor(const QColor &shadowColor);


V. Core Code

void ShadowClock::drawArc(QPainter *painter, int radius, qreal angle)

    int smallradius = radius - radiusWidth;
    int maxRaidus = radius + shadowWidth;
    int minRadius = smallradius - shadowWidth;

    //Use circular gradient to form halo effect
    QRadialGradient radialGradient(QPointF(0, 0), maxRaidus);
    QColor color = shadowColor;
    QColor lightColor = shadowColor.lighter(100);

    radialGradient.setColorAt(0, color);
    radialGradient.setColorAt(minRadius * 1.0 / maxRaidus, color);
    radialGradient.setColorAt(smallradius * 1.0 / maxRaidus, color);

    radialGradient.setColorAt((smallradius + 1) * 1.0 / maxRaidus, lightColor);
    radialGradient.setColorAt((radius - 1) * 1.0 / maxRaidus, lightColor);
    radialGradient.setColorAt(radius * 1.0 / maxRaidus, color);
    radialGradient.setColorAt(1, color);

    painter->drawPie(-maxRaidus, -maxRaidus, maxRaidus * 2, maxRaidus * 2, 90 * 16, -angle * 16);

void ShadowClock::drawText(QPainter *painter)

    QFont font;

    QDateTime now = QDateTime::currentDateTime();
    QFontMetricsF fm(font);
    QStringList textList;
    textList << now.toString("MM month dd day yyyy") << now.toString("hh:mm:ss.zzz");

    //Drawing Text Path
    QPainterPath textPath;
    textPath.addText(-fm.width(textList.at(0)) / 2.0, -fm.lineSpacing() / 2.0, font, textList.at(0));
    textPath.addText(-fm.width(textList.at(1)) / 2.0, fm.lineSpacing() / 2.0, font, textList.at(1));

    QColor strokeColor = textColor.light(80);
    painter->strokePath(textPath, QPen(strokeColor, shadowWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));


Introduction of Control

  1. More than 160 exquisite controls, covering a variety of dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlighted buttons, sliding selectors, the lunar calendar and so on. Far more controls than qwt integrates.
  2. Each class can be separated into a separate control, zero-coupling, each control has a header file and an implementation file, independent of other files, to facilitate the integration of a single control in the form of source code into the project, less code. The control classes of qwt are interlinked and highly coupled. If you want to use one of the controls, you must include all the code.
  3. All pure Qt writing, QWidget+QPainter drawing, support any Qt version from Qt4.6 to Qt5.13, support mingw, msvc, gcc and other compilers, support any operating system such as windows+linux+mac + embedded linux, no scrambling, can be directly integrated into Qt Creator, as with its own controls, most of the effects can be set as few attributes, very convenient.
  4. Each control has a corresponding separate DEMO containing the source code of the control, which is convenient for reference. It also provides an integrated DEMO for all controls.
  5. The source code of each control has detailed Chinese annotations, which are compiled in accordance with the unified design specifications. It is convenient to learn how to compile custom controls.
  6. Each control's default color matching and demo's corresponding color matching are very beautiful.
  7. More than 130 visible controls and 6 invisible controls.
  8. Some controls provide a variety of style choices, a variety of indicator style choices.
  9. All controls adapt to form stretching changes.
  10. Integrate custom control property designer, support drag design, WYSIWYG, support import and export xml format.
  11. With activex control demo, all controls can run directly in ie browser.
  12. Integrate fontawesome graphic fonts + hundreds of graphic fonts collected by Alibaba iconfont to enjoy the fun of graphic fonts.
  13. All controls eventually generate a dynamic library file (dll or so, etc.) that can be directly integrated into the qtcreator to drag the design to use.
  14. At present, there is a version of qml, pyqt version will be considered later, if the user demand is large.
  15. Custom Control Plug-in Open Dynamic Library (permanently free), without any backdoor and restrictions, please feel free to use.
  16. At present, 32 versions of dll have been provided, of which qt_5_7_0_mingw530_32 will always guarantee the latest integrity.
  17. Increase control and improve control from time to time, update SDK from time to time. Welcome to make suggestions. Thank you!
  18. Qt introductory books recommend Hoyafei's Quick Start to Qt Creator, Qt5 Programming Introduction, and Qt advanced books recommend the official C++ GUI Qt4 Programming.
  19. I strongly recommend programmers'self-cultivation and planning series "Talking about Programmers", "Programmers' Growth Course" and "Solution Programmers". They benefit a lot and benefit a lifetime!
  20. SDK address: https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk

Tags: Mobile Qt Qt5 Linux SDK

Posted on Thu, 10 Oct 2019 21:56:48 -0400 by ThunderVike