hunt978 |
2017-09-03 14:31 |
llwj0303:能不能分享下代码,那个offset是什么额
參數解釋: - using PercentStyle = enum {
PercentStyle_Rect, // 矩形 PercentStyle_Circle, // 圓形 PercentStyle_Ellipse // 橢圓 }; uint32_t value; // 當前值 uint32_t minValue; // 最小值,通常0 uint32_t maxValue; // 最大值,通常100 uint32_t waterDensity; // 波紋數量,最小1 double waterHeight; // 波紋高度比例相對於控件高度,通常0.02 double offset; // 波紋位置,控件自主維護的,初始值0 PercentStyle percentStyle; // 波紋類型 uint32_t borderWidth; // 邊界寬度,可設置為3 QColor usedColor; // 波紋顏色
如果要達成動態變化的,可以使用兩種方式,QTimer事件或者QProperyAnimation。以下是QTimer方式
- auto* timer = new QTimer(this);
connect(timer, &QTimer::timeout, [=]() { offset += 0.6; // 原繪製方法在paintEvent時更新offset,但會導致控件大小變化等事件發生時導致波紋運動,故最好自主更新 update(); }); timer->start(100);
主繪製函數
- void ProgressBarWater::paintEvent(QPaintEvent* event) {
QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); drawValue(&painter); // \TODO 在此可以添加繪製邊框、繪製文字等等事件 }
代碼如下:
- /*******************************************************************************
* filename : ProgressBarWater.hpp * create : 2017-08-30 02:41:03 UTC * modified : 2017-08-30 03:16:48 UTC \******************************************************************************/
#ifndef __PROGRESS_BAR_WATER_HPP__ #define __PROGRESS_BAR_WATER_HPP__
//////////////////////////////////////////////////////////////////////////////// // Headers // #include <QColor> #include <QWidget> #include <cstdint>
//////////////////////////////////////////////////////////////////////////////// // Typedefs & Constants //
//////////////////////////////////////////////////////////////////////////////// // Classes // class ProgressBarWater : public QWidget { Q_OBJECT
public: explicit ProgressBarWater(QWidget* parent = nullptr); ~ProgressBarWater();
public: using PercentStyle = enum { PercentStyle_Rect, PercentStyle_Circle, PercentStyle_Ellipse };
protected: void drawValue(QPainter* painter); void paintEvent(QPaintEvent* event);
private: uint32_t value; uint32_t minValue; uint32_t maxValue; uint32_t waterDensity; double waterHeight; double offset; PercentStyle percentStyle; uint32_t borderWidth; QColor usedColor; }; //////////////////////////////////////////////////////////////////////////////// // Functions //
#endif // __PROGRESS_BAR_WATER_HPP__ ////////////////////////////////// EOF /////////////////////////////////////////
- /*******************************************************************************
* filename : ProgressBarWater.cpp * create : 2017-08-30 02:41:03 UTC * modified : 2017-08-30 03:16:44 UTC \******************************************************************************/
//////////////////////////////////////////////////////////////////////////////// // Headers // #include <QtWidgets>
#include "ProgressBarWater.hpp"
//////////////////////////////////////////////////////////////////////////////// // Typedefs & Constants //
//////////////////////////////////////////////////////////////////////////////// // Inner Scope Objects //
//////////////////////////////////////////////////////////////////////////////// // Classes // ProgressBarWater::ProgressBarWater(QWidget* parent) : QWidget(parent) { value = 45; minValue = 0; maxValue = 100; waterDensity = 2; waterHeight = 0.02; offset = 0; percentStyle = PercentStyle_Rect; borderWidth = 2; usedColor = Qt::red;
auto* timer = new QTimer(this); connect(timer, &QTimer::timeout, [=]() { offset += 0.6; update(); }); timer->start(100); }
ProgressBarWater::~ProgressBarWater() {}
void ProgressBarWater::paintEvent(QPaintEvent* event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); drawValue(&painter); }
void ProgressBarWater::drawValue(QPainter* painter) { int height = this->height(); int width = this->width(); int side = qMin(width, height); //计算当前值所占百分比 double percent = 1 - (double)(value - minValue) / (maxValue - minValue); //正弦曲线公式 y = A * sin(ωx + φ) + k // w表示周期,可以理解为水波的密度,值越大密度越大(浪越密集 ^_^),取值 // 密度*M_PI/宽度 double w = waterDensity * M_PI / width; // A表示振幅,可以理解为水波的高度,值越大高度越高(越浪 ^_^),取值高度的百分比 double A = height * waterHeight; // k表示y轴偏移,可以理解为进度,取值高度的进度百分比 double k = height * percent; //第一条波浪路径集合 QPainterPath waterPath1; //第二条波浪路径集合 QPainterPath waterPath2; //移动到左上角起始点 waterPath1.moveTo(0, height); waterPath2.moveTo(0, height); // offset += 0.6; if (offset > (width / 2)) { offset = 0; } for (int x = 0; x <= width; x++) { //第一条波浪Y轴 double waterY1 = (double)(A * sin(w * x + offset)) + k; //第二条波浪Y轴 double waterY2 = (double)(A * sin(w * x + offset + (width / 2 * w))) + k; //如果当前值为最小值则Y轴为高度 if (this->value == minValue) { waterY1 = height; waterY2 = height; } //如果当前值为最大值则Y轴为0 if (this->value == maxValue) { waterY1 = 0; waterY2 = 0; } waterPath1.lineTo(x, waterY1); waterPath2.lineTo(x, waterY2); } //移动到右下角结束点,整体形成一个闭合路径 waterPath1.lineTo(width, height); waterPath2.lineTo(width, height); //大路径 QPainterPath bigPath; if (percentStyle == PercentStyle_Rect) { width = width - borderWidth * 2; height = height - borderWidth * 2; bigPath.addRect(borderWidth, borderWidth, width, height); } else if (percentStyle == PercentStyle_Circle) { side = side - borderWidth * 2; bigPath.addEllipse((width - side) / 2, borderWidth, side, side); } else if (percentStyle == PercentStyle_Ellipse) { width = width - borderWidth * 2; height = height - borderWidth * 2; bigPath.addEllipse(borderWidth, borderWidth, width, height); } painter->save(); //新路径,用大路径减去波浪区域的路径,形成遮罩效果 QPainterPath path; painter->setPen(Qt::NoPen); QColor waterColor1 = usedColor; waterColor1.setAlpha(100); QColor waterColor2 = usedColor; waterColor2.setAlpha(180); //第一条波浪挖去后的路径 path = bigPath.intersected(waterPath1); painter->setBrush(waterColor1); painter->drawPath(path); //第二条波浪挖去后的路径 path = bigPath.intersected(waterPath2); painter->setBrush(waterColor2); painter->drawPath(path); painter->restore(); }
//////////////////////////////////////////////////////////////////////////////// // Functions //
////////////////////////////////// EOF /////////////////////////////////////////
- /*******************************************************************************
* filename : main.cpp * create : 2017-08-30 02:43:20 UTC * modified : 2017-08-30 03:16:50 UTC \******************************************************************************/
//////////////////////////////////////////////////////////////////////////////// // Headers // #include <QApplication>
#include "ProgressBarWater.hpp"
//////////////////////////////////////////////////////////////////////////////// // Typedefs & Constants //
//////////////////////////////////////////////////////////////////////////////// // Inner Scope Objects //
//////////////////////////////////////////////////////////////////////////////// // Classes //
//////////////////////////////////////////////////////////////////////////////// // Functions // int main(int argc, char* argv[]) { QApplication app(argc, argv);
ProgressBarWater _ProgressBarWater; _ProgressBarWater.show();
return app.exec(); }
////////////////////////////////// EOF /////////////////////////////////////////
|
|