在上一篇文章写了个高仿WIN10系统的光晕日历,此次来绘制一个光晕的时钟,也是在某些网页上看到的效果,时分秒分别以进度条的形式来绘制,并且这个进度条带有光晕效果,中间的日期时间文字也是光晕效果,总体看起来有点科幻的感受,本控件没有什么技术难点,若是真要有难点的话也就是如何产生这个光晕效果,在使用painter绘制的时候,设置画笔,能够设置brush,brush能够是各类渐变效果,这个就很是强大了,主要有线性渐变、圆形渐变、锥形渐变,这三种渐变用得好,各类效果都驾轻就熟随手拈来。
为了产生光晕效果,须要用到圆形渐变,并对圆形渐变中的不一样的位置设置透明度值来处理,时分秒对应的进度能够自动计算出来,这个不难,好比直接用QTime能够获取对应的时分秒,而后时钟和分钟除以60,秒钟除以1000来获取对应的进度。绘制光晕文本采用的QPainterPath的addText来实现。linux
#ifndef SHADOWCLOCK_H #define SHADOWCLOCK_H /** * 光晕时钟控件 做者:雨田哥(QQ:3246214072) 整理:feiyangqingyun(QQ:517216493) 2019-10-07 * 1:可设置圆弧半径宽度 * 2:可设置光晕宽度 * 3:可设置光晕颜色 * 4:可设置文本颜色 * 5:采用动画机制平滑进度展现时间 */ #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 ShadowClock : public QWidget #else class ShadowClock : public QWidget #endif { Q_OBJECT 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) public: explicit ShadowClock(QWidget *parent = 0); ~ShadowClock(); protected: void paintEvent(QPaintEvent *); void drawArc(QPainter *painter, int radius, qreal angle); void drawText(QPainter *painter); private: int radiusWidth; //半径宽度 int shadowWidth; //光晕宽度 QColor textColor; //文本颜色 QColor shadowColor; //光晕颜色 public: int getRadiusWidth() const; int getShadowWidth() const; QColor getTextColor() const; QColor getShadowColor() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //设置半径宽度+光晕宽度 void setRadiusWidth(int radiusWidth); void setShadowWidth(int shadowWidth); //设置文本颜色+光晕颜色 void setTextColor(const QColor &textColor); void setShadowColor(const QColor &shadowColor); }; #endif // SHADOWCLOCK_H
void ShadowClock::drawArc(QPainter *painter, int radius, qreal angle) { painter->save(); painter->setPen(Qt::NoPen); int smallradius = radius - radiusWidth; int maxRaidus = radius + shadowWidth; int minRadius = smallradius - shadowWidth; //采用圆形渐变,造成光晕效果 QRadialGradient radialGradient(QPointF(0, 0), maxRaidus); QColor color = shadowColor; QColor lightColor = shadowColor.lighter(100); color.setAlphaF(0); radialGradient.setColorAt(0, color); radialGradient.setColorAt(minRadius * 1.0 / maxRaidus, color); color.setAlphaF(0.5); 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); color.setAlphaF(0); radialGradient.setColorAt(1, color); painter->setBrush(radialGradient); painter->drawPie(-maxRaidus, -maxRaidus, maxRaidus * 2, maxRaidus * 2, 90 * 16, -angle * 16); painter->restore(); } void ShadowClock::drawText(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); QFont font; font.setBold(true); font.setPointSize(10); painter->setFont(font); QDateTime now = QDateTime::currentDateTime(); QFontMetricsF fm(font); QStringList textList; textList << now.toString("MM月dd日yyyy") << now.toString("hh:mm:ss.zzz"); //绘制文本路径 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); strokeColor.setAlphaF(0.2); painter->strokePath(textPath, QPen(strokeColor, shadowWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->setBrush(textColor); painter->drawPath(textPath); painter->restore(); }