-
UID:178418
-
- 注册时间2017-01-14
- 最后登录2020-10-18
- 在线时间31小时
-
- 发帖6
- 搜Ta的帖子
- 精华0
- 金钱70
- 威望16
- 贡献值0
- 好评度6
-
访问TA的空间加好友用道具
|
回 llwj0303 的帖子
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 /////////////////////////////////////////
|