回复: Qt编写水波进度条控件
#16 [核心科技 08-29 21:26]
牛!!!
#17 回 王闯闯 的帖子 [llwj0303 09-01 17:36]
王闯闯:大师,厉害!
照着大师的代码简单实现了下
(2017-08-24 15:35)
能不能分享下代码,那个offset是什么额
#18 回 llwj0303 的帖子 [hunt978 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 : 2 ..
#19 [liudianwu 09-03 16:21]
以上代码会有问题,当类型为圆形,高度大于宽度时,变形严重。正确代码如下:
void ProgressBarWater::drawValue(QPainter *painter)
{
int height = this-> height();
int width = this->width();
int side = qMin(width, height);
//起始点坐标和结束点坐标
int startX = borderWidth;
int startY = borderWidth;
int endX = width - borderWidth;
int endY = height - borderWidth;
//圆形的区域要重新计算
if (percentStyle == PercentStyle_Circle) {
side = side - borderWidth * 2;
startX = (width - side) / 2;
startY = (height - side) / 2;
endX = (width + side) / 2;
endY = (height + side) / 2;
}
//计算当前值所占百分比
double percent = 1 - (double)(value - minValue) / (maxValue - minValue);
//正弦曲线公式 y = A * sin(ωx + φ) + k
//w表示周期,可以理解为水波的密度,值越大密度越大(浪越密集 ^_^),取值 密度*M_PI/宽度
double w = waterDensity * M_PI / endX;
//A表示振幅,可以理解为水波的高度,值越大高度越高(越浪 ^_^),取值高度的百分比
double A = endY * waterHeight;
//k表示y轴偏移,可以理解为进度,取值高度的进度百分比
double k = endY * percent;
//圆形的区域要重新计算
if (percentStyle == PercentStyle_Circle) {
k = (side * percent) + startY;
}
// ..
#20 [story2016 09-03 16:37]
厉害 原来思路是这样,不过上下幅值低些更美观