赞
踩
前言
环形进度条,用来展示当前进度,为了满足大屏UI的需要特意定制,以前有个叫圆环进度条,不能满足项目需要,只能重新定做,以前的进度间距不能自适应分辨率,而且当前进度对应的反的进度不能单独设置颜色,即当前进度90%,剩余的10%也需要设置成不同的颜色,还有一个重要的功能是,能够指定多个警戒值,一旦超过或者小于该值,则当前进度自动切换到预先设定的警戒值颜色,而不需要用户自己去判断警戒值去设置警戒颜色,用户只需要传入当前值即可,这个功能非常实用,还可以设置警戒判断的标准是超过值还是小于值报警。个人感觉这个环形进度条功能完爆市面上所有的圆环进度条。只要稍作参数设置可以变成各种想要的效果,什么起始角度+动画效果+顺时针逆时针转等。
实现的功能
效果图
核心代码
void ProgressRing::paintEvent(QPaintEvent *){ int width = this->width(); int height = this->height(); int side = qMin(width, height); //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); painter.translate(width / 2, height / 2); painter.scale(side / 200.0, side / 200.0); //绘制背景 drawBg(&painter); //绘制进度 drawRing(&painter); //绘制间隔,重新绘制一个圆遮住,产生间距效果 if (ringPadding > 0) { drawPadding(&painter); } //绘制中间圆 drawCircle(&painter); //绘制当前值 drawValue(&painter);}void ProgressRing::drawBg(QPainter *painter){ int radius = 99; painter->save(); painter->setPen(Qt::NoPen); //这里有个技巧,如果没有间距则设置成圆环的背景色 painter->setBrush(ringPadding == 0 ? ringBgColor : bgColor); painter->drawEllipse(-radius, -radius, radius * 2, radius * 2); painter->restore();}void ProgressRing::drawRing(QPainter *painter){ int radius = 99 - ringPadding; painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(ringColor); QRectF rect(-radius, -radius, radius * 2, radius * 2); //计算总范围角度,当前值范围角度,剩余值范围角度 double angleAll = 360.0; double angleCurrent = angleAll * ((currentValue - minValue) / (maxValue - minValue)); double angleOther = angleAll - angleCurrent; //如果逆时针 if (!clockWise) { angleCurrent = -angleCurrent; angleOther = -angleOther; } //动态设置当前进度颜色 QColor color = ringColor; if (alarmMode == 1) { if (currentValue >= ringValue3) { color = ringColor3; } else if (currentValue >= ringValue2) { color = ringColor2; } else { color = ringColor1; } } else if (alarmMode == 2) { if (currentValue <= ringValue1) { color = ringColor1; } else if (currentValue <= ringValue2) { color = ringColor2; } else { color = ringColor3; } } //绘制当前值饼圆 painter->setBrush(color); painter->drawPie(rect, (startAngle - angleCurrent) * 16, angleCurrent * 16); //绘制剩余值饼圆 painter->setBrush(ringBgColor); painter->drawPie(rect, (startAngle - angleCurrent - angleOther) * 16, angleOther * 16); painter->restore();}void ProgressRing::drawPadding(QPainter *painter){ int radius = 99 - ringWidth - ringPadding; painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(bgColor); painter->drawEllipse(-radius, -radius, radius * 2, radius * 2); painter->restore();}void ProgressRing::drawCircle(QPainter *painter){ //文字的区域要减去进度的宽度及间距 int radius = 99 - ringWidth - (ringPadding * 2); painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(circleColor); painter->drawEllipse(-radius, -radius, radius * 2, radius * 2); painter->restore();}void ProgressRing::drawValue(QPainter *painter){ //文字的区域要减去进度的宽度及间距 int radius = 99 - ringWidth - (ringPadding * 2); painter->save(); painter->setPen(textColor); QFont font; int fontSize = radius - (showPercent ? 20 : 6); font.setPixelSize(fontSize); painter->setFont(font); QRectF textRect(-radius, -radius, radius * 2, radius * 2); QString strValue; if (showPercent) { double percent = (currentValue * 100) / (maxValue - minValue); strValue = QString("%1%").arg(percent, 0, 'f', precision); } else { strValue = QString("%1").arg(currentValue, 0, 'f', precision); } painter->drawText(textRect, Qt::AlignCenter, strValue); painter->restore();}
欢迎提出改进意见,谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。