Qt編寫自定義控件66-光暈時鐘

1、前言

在上一篇文章寫了個高仿WIN10系統的光暈日曆,此次來繪製一個光暈的時鐘,也是在某些網頁上看到的效果,時分秒分別以進度條的形式來繪製,並且這個進度條帶有光暈效果,中間的日期時間文字也是光暈效果,總體看起來有點科幻的感受,本控件沒有什麼技術難點,若是真要有難點的話也就是如何產生這個光暈效果,在使用painter繪製的時候,設置畫筆,能夠設置brush,brush能夠是各類漸變效果,這個就很是強大了,主要有線性漸變、圓形漸變、錐形漸變,這三種漸變用得好,各類效果都駕輕就熟隨手拈來。
爲了產生光暈效果,須要用到圓形漸變,並對圓形漸變中的不一樣的位置設置透明度值來處理,時分秒對應的進度能夠自動計算出來,這個不難,好比直接用QTime能夠獲取對應的時分秒,而後時鐘和分鐘除以60,秒鐘除以1000來獲取對應的進度。繪製光暈文本採用的QPainterPath的addText來實現。linux

2、實現的功能

  • 1:可設置圓弧半徑寬度
  • 2:可設置光暈寬度
  • 3:可設置光暈顏色
  • 4:可設置文本顏色
  • 5:採用動畫機制平滑進度展現時間

3、效果圖

4、頭文件代碼

#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

5、核心代碼

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();
}

6、控件介紹

  1. 超過160個精美控件,涵蓋了各類儀表盤、進度條、進度球、指南針、曲線圖、標尺、溫度計、導航條、導航欄,flatui、高亮按鈕、滑動選擇器、農曆等。遠超qwt集成的控件數量。
  2. 每一個類均可以獨立成一個單獨的控件,零耦合,每一個控件一個頭文件和一個實現文件,不依賴其餘文件,方便單個控件以源碼形式集成到項目中,較少代碼量。qwt的控件類環環相扣,高度耦合,想要使用其中一個控件,必須包含全部的代碼。
  3. 所有純Qt編寫,QWidget+QPainter繪製,支持Qt4.6到Qt5.13的任何Qt版本,支持mingw、msvc、gcc等編譯器,支持任意操做系統好比windows+linux+mac+嵌入式linux等,不亂碼,可直接集成到Qt Creator中,和自帶的控件同樣使用,大部分效果只要設置幾個屬性便可,極爲方便。
  4. 每一個控件都有一個對應的單獨的包含該控件源碼的DEMO,方便參考使用。同時還提供一個全部控件使用的集成的DEMO。
  5. 每一個控件的源代碼都有詳細中文註釋,都按照統一設計規範編寫,方便學習自定義控件的編寫。
  6. 每一個控件默認配色和demo對應的配色都很是精美。
  7. 超過130個可見控件,6個不可見控件。
  8. 部分控件提供多種樣式風格選擇,多種指示器樣式選擇。
  9. 全部控件自適應窗體拉伸變化。
  10. 集成自定義控件屬性設計器,支持拖曳設計,所見即所得,支持導入導出xml格式。
  11. 自帶activex控件demo,全部控件能夠直接運行在ie瀏覽器中。
  12. 集成fontawesome圖形字體+阿里巴巴iconfont收藏的幾百個圖形字體,享受圖形字體帶來的樂趣。
  13. 全部控件最後生成一個動態庫文件(dll或者so等),能夠直接集成到qtcreator中拖曳設計使用。
  14. 目前已經有qml版本,後期會考慮出pyqt版本,若是用戶需求量很大的話。
  15. 自定義控件插件開放動態庫使用(永久免費),無任何後門和限制,請放心使用。
  16. 目前已提供32個版本的dll,其中qt_5_7_0_mingw530_32這個版本會一直保證最新的完整的。
  17. 不按期增長控件和完善控件,不按期更新SDK,歡迎各位提出建議,謝謝!
  18. Qt入門書籍推薦霍亞飛的《Qt Creator快速入門》《Qt5編程入門》,Qt進階書籍推薦官方的《C++ GUI Qt4編程》。
  19. 強烈推薦程序員自我修養和規劃系列書《大話程序員》《程序員的成長課》《解憂程序員》,受益不淺,受益終生!
  20. SDK地址:https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk
相關文章
相關標籤/搜索