|
本帖最后由 liudianwu 于 2017-8-25 14:44 编辑
手机app中经常能见到各种各样的水波进度条之类的效果,觉得不错,用QWidget的QPainter绘制了一个。集成到了QUC自定义控件中。原理是利用正弦曲线产生平滑曲线点集合,然后用大路径减去当前进度路径,形成水波效果。
/**
* 水波进度条控件 作者:feiyangqingyun(QQ:517216493) 2017-8-23
* 1:可设置范围值,支持负数值
* 2:可设置水波密度,密度越大浪越多
* 3:可设置水波高度,高度越大越浪
* 4:可设置边框宽度
* 5:可设置是否显示进度值
* 6:可设置进度值是否为百分比格式
* 7:可设置背景颜色、边框颜色、当前进度颜色、文字颜色
* 8:提供三种样式风格选择 方形风格 圆形风格 椭圆风格
*/
核心代码:
- 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();
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|