在上一篇文章寫了個高仿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(); }