1、前言
隨着移動互聯網的盛行,如今手機APP大行其道,每一個人的手機沒有十幾個APP都很差意思說本身是現代人,各類聊天、購物、直播、小視頻等APP,有個陌生人社交的APP叫探探,本人用過幾回,固然不是去爲了找對象,而是純粹爲了好玩研究下他的U設計和軟件邏輯流程等,其中有個雷達控件,單擊之後能夠搜索附近的異性進行配對,這個雷達控件的效果蠻好的,因而手癢琢磨着用Qt來實現一個,畢竟本身寫了150多個控件了,已經上癮了,對各類效果都如魚得水,看到各類效果都不天然的想到編碼思路等。 這個控件的核心其實就是外圍的那個掃描圈和發散的掃描線,中間變大變小恢復正常的圓形頭像,外圍的掃描圈採用錐形漸變顏色,經過透明度控制造成掃描效果,核心方法就是drawPie,至於擴散圈,須要識別到單擊之後將擴散圈存入隊列,由於可能會單擊屢次,產生多個擴散圈,至於中間頭像的動態效果,採用三個QPropertyAnimation來實現,一個負責變大,一個負責變小,一個負責恢復正常,而後三個動畫加入到QSequentialAnimationGroup動畫序列中,按照順序執行。linux
2、實現的功能
- 1:可設置中間圖像
- 2:可設置圖像的邊框寬度+邊框顏色,產生圓形圖像效果
- 3:可設置掃描線的最大半徑
- 4:可設置掃描線的邊框寬度
- 5:可設置擴散圈的線條寬度
- 6:可設置掃描線的每次移動的步長
- 7:可設置擴散圈的每次移動的步長
- 8:可設置掃描線的顏色
- 9:可設置擴散圈的顏色
3、效果圖
4、頭文件代碼
#ifndef SCANTANTAN_H #define SCANTANTAN_H /** * 探探雷達控件 做者:東門吹雪(QQ:709102202) 整理:feiyangqingyun(QQ:517216493) 2019-10-01 * 1:可設置中間圖像 * 2:可設置圖像的邊框寬度+邊框顏色,產生圓形圖像效果 * 3:可設置掃描線的最大半徑 * 4:可設置掃描線的邊框寬度 * 5:可設置擴散圈的線條寬度 * 6:可設置掃描線的每次移動的步長 * 7:可設置擴散圈的每次移動的步長 * 8:可設置掃描線的顏色 * 9:可設置擴散圈的顏色 */ #include <QWidget> class QSequentialAnimationGroup; #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include <QtDesigner/QDesignerExportWidget> #else #include <QtUiPlugin/QDesignerExportWidget> #endif class QDESIGNER_WIDGET_EXPORT ScanTanTan : public QWidget #else class ScanTanTan : public QWidget #endif { Q_OBJECT Q_PROPERTY(QPixmap image READ getImage WRITE setImage) Q_PROPERTY(int imageBorderWidth READ getImageBorderWidth WRITE setImageBorderWidth) Q_PROPERTY(QColor imageBorderColor READ getImageBorderColor WRITE setImageBorderColor) Q_PROPERTY(int scanRadius READ getScanRadius WRITE setScanRadius) Q_PROPERTY(int scanWidth READ getScanWidth WRITE setScanWidth) Q_PROPERTY(int ringWidth READ getRingWidth WRITE setRingWidth) Q_PROPERTY(int scanStep READ getScanStep WRITE setScanStep) Q_PROPERTY(int ringStep READ getRingStep WRITE setRingStep) Q_PROPERTY(QColor scanColor READ getScanColor WRITE setScanColor) Q_PROPERTY(QColor ringColor READ getRingColor WRITE setRingColor) public: struct RingData { int radius; //半徑 float width; //畫筆粗細 int alpha; //透明度 }; explicit ScanTanTan(QWidget *parent = 0); protected: void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void paintEvent(QPaintEvent *); void drawScan(QPainter *painter); void drawRing(QPainter *painter); void drawImage(QPainter *painter); private slots: void changeScan(); void changeRing(); void updateImage(const QVariant &value); double twoPtDistance(const QPointF &pt1, const QPointF &pt2); private: QPixmap image; //中間圖片 int imageBorderWidth; //圖片邊框寬度 QColor imageBorderColor;//圖片邊框顏色 int scanRadius; //掃描線最大半徑 int scanWidth; //掃描線邊框寬度 int ringWidth; //擴散圈線條寬度 int scanStep; //掃描線每次移動的步長 int ringStep; //擴散圈每次移動的步長 QColor scanColor; //掃描線顏色 QColor ringColor; //擴散圈顏色 bool isPressed; //鼠標是否按下 int ringRadius; //擴散圈半徑 int imageRadius; //圖片半徑 int scanDeg; //當前掃描線角度 //擴散圈集合,鼠標可能按下屢次則產生多個擴散圈,用隊列存起來 QList<RingData> rings; //動畫組合,用於中間圖片的變大放小 QSequentialAnimationGroup *animationGroup; public: QPixmap getImage() const; int getImageBorderWidth() const; QColor getImageBorderColor()const; int getScanRadius() const; int getScanWidth() const; int getRingWidth() const; int getScanStep() const; int getRingStep() const; QColor getScanColor() const; QColor getRingColor() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //設置圖片+圖片邊框寬度+圖片邊框顏色 void setImage(const QPixmap &image); void setImageBorderWidth(int imageBorderWidth); void setImageBorderColor(const QColor &imageBorderColor); //設置掃描線最大半徑+掃描線邊框寬度+擴散圈線條寬度 void setScanRadius(int scanRadius); void setScanWidth(int scanWidth); void setRingWidth(int ringWidth); //設置掃描線步長+擴散圈步長 void setScanStep(int scanStep); void setRingStep(int ringStep); //設置掃描線顏色+擴散圈顏色 void setScanColor(const QColor &scanColor); void setRingColor(const QColor &ringColor); }; #endif // SCANTANTAN_H
5、核心代碼
void ScanTanTan::paintEvent(QPaintEvent *) { int width = this->width(); int height = this->height(); int side = qMin(width, height); //繪製準備工做,啓用反鋸齒,平移座標軸中心,等比例縮放 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); painter.translate(width / 2, height / 2); painter.scale(side / 200.0, side / 200.0); //繪製掃描線 drawScan(&painter); //繪製擴散圈 drawRing(&painter); //繪製中間圖片 drawImage(&painter); } void ScanTanTan::drawScan(QPainter *painter) { painter->save(); //錐形漸變顏色,經過透明度控制造成掃描效果 QConicalGradient conicalGradient(0, 0, scanDeg); QColor color = scanColor; color.setAlpha(50); conicalGradient.setColorAt(0, color); color.setAlpha(0); conicalGradient.setColorAt(1, color); //設置畫筆畫刷 QPen pen; pen.setWidth(scanWidth); pen.setBrush(conicalGradient); painter->setPen(pen); painter->setBrush(conicalGradient); //繪製餅圓 QRect rect(-scanRadius, -scanRadius, scanRadius * 2, scanRadius * 2); painter->drawPie(rect, scanDeg * 16, 360 * 16); painter->restore(); } void ScanTanTan::drawRing(QPainter *painter) { painter->save(); painter->setBrush(Qt::NoBrush); //繪製全部擴散圈,擴散圈其實就是個沒有背景顏色的圓形 for (int i = 0; i < rings.count(); i++) { RingData ring = rings.at(i); int radius = ring.radius; float width = ring.width; int alpha = 255 - ring.alpha; QColor color = ringColor; color.setAlpha(alpha); QPen pen; pen.setWidthF(width); pen.setColor(color); painter->setPen(pen); painter->drawEllipse(-radius, -radius, radius * 2, radius * 2); } painter->restore(); } void ScanTanTan::drawImage(QPainter *painter) { painter->save(); //設置圓形遮罩路徑,產生圓形頭像效果 QPainterPath path; path.addEllipse(QPoint(0, 0), imageRadius, imageRadius); painter->setClipPath(path); //繪製圖片 QRect rect(-imageRadius, -imageRadius, imageRadius * 2, imageRadius * 2); painter->drawPixmap(rect, image); //繪製圖片邊緣圓形 QPen pen; pen.setWidth(imageBorderWidth); pen.setColor(imageBorderColor); painter->setPen(pen); painter->setBrush(Qt::NoBrush); //如下兩種方法二選一,其實繪製360度的圓弧=繪製無背景的圓形 //painter->drawArc(rect, 0, 360 * 16); painter->drawEllipse(rect); painter->restore(); }
6、控件介紹
- 超過160個精美控件,涵蓋了各類儀表盤、進度條、進度球、指南針、曲線圖、標尺、溫度計、導航條、導航欄,flatui、高亮按鈕、滑動選擇器、農曆等。遠超qwt集成的控件數量。
- 每一個類均可以獨立成一個單獨的控件,零耦合,每一個控件一個頭文件和一個實現文件,不依賴其餘文件,方便單個控件以源碼形式集成到項目中,較少代碼量。qwt的控件類環環相扣,高度耦合,想要使用其中一個控件,必須包含全部的代碼。
- 所有純Qt編寫,QWidget+QPainter繪製,支持Qt4.6到Qt5.13的任何Qt版本,支持mingw、msvc、gcc等編譯器,支持任意操做系統好比windows+linux+mac+嵌入式linux等,不亂碼,可直接集成到Qt Creator中,和自帶的控件同樣使用,大部分效果只要設置幾個屬性便可,極爲方便。
- 每一個控件都有一個對應的單獨的包含該控件源碼的DEMO,方便參考使用。同時還提供一個全部控件使用的集成的DEMO。
- 每一個控件的源代碼都有詳細中文註釋,都按照統一設計規範編寫,方便學習自定義控件的編寫。
- 每一個控件默認配色和demo對應的配色都很是精美。
- 超過130個可見控件,6個不可見控件。
- 部分控件提供多種樣式風格選擇,多種指示器樣式選擇。
- 全部控件自適應窗體拉伸變化。
- 集成自定義控件屬性設計器,支持拖曳設計,所見即所得,支持導入導出xml格式。
- 自帶activex控件demo,全部控件能夠直接運行在ie瀏覽器中。
- 集成fontawesome圖形字體+阿里巴巴iconfont收藏的幾百個圖形字體,享受圖形字體帶來的樂趣。
- 全部控件最後生成一個動態庫文件(dll或者so等),能夠直接集成到qtcreator中拖曳設計使用。
- 目前已經有qml版本,後期會考慮出pyqt版本,若是用戶需求量很大的話。
- 自定義控件插件開放動態庫使用(永久免費),無任何後門和限制,請放心使用。
- 目前已提供26個版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
- 不按期增長控件和完善控件,不按期更新SDK,歡迎各位提出建議,謝謝!
- Qt入門書籍推薦霍亞飛的《Qt Creator快速入門》《Qt5編程入門》,Qt進階書籍推薦官方的《C++ GUI Qt4編程》。
- 強烈推薦程序員自我修養和規劃系列書《大話程序員》《程序員的成長課》《解憂程序員》,受益不淺,受益終生!
- SDK地址:https://gitee.com/feiyangqingyun/QUCSDK