多态进度条,顾名思义,有多重状态,其实本控件主要是用来表示百分比进度的,由于之前已经存在了百分比进度条控件,名字被霸占了,按照先来先得原则,只好另外取个别名叫做多态进度条,应用场景是,某种任务有三种状态,比如正常状态、警戒状态、报警状态,这三种状态都分别有一个占比,需要用不同的颜色表示,这样就衍生出了此控件,类似于堆积图。接下来节假日四天,可以全身心投入研发还未完工的大屏UI程序,基础控件部分+二级界面部分都已经做好,现在专心整合到主界面和打通数据流(采用数据库采集+网络采集两种方式)。多态进度条也是为了此项目特意定制的。
实现的功能
- 1:可设置三种状态不同的值
- 2:可设置三种状态不同的颜色
- 3:可设置圆角角度
- 4:可设置启用自动圆角
- 5:可设置边框宽度+颜色
- 6:可设置是否显示值或者百分比
- 7:可设置字体自适应大小
- 8:可设置背景颜色+文字颜色
- 9:精准计算圆角角度,解决了QSS中border-radius当进度小于圆角角度出现方形的BUG
效果图
核心代码
void ProgressThree::paintEvent(QPaintEvent *){ //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); if (autoRadius) { radius = this->height() / 2; } //绘制背景 drawBg(&painter); //绘制值1 drawValue1(&painter); //绘制值2 drawValue2(&painter); //绘制值3 drawValue3(&painter); //最后绘制边框盖上去 drawBorder(&painter);}void ProgressThree::drawBg(QPainter *painter){ painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(bgColor); painter->drawRoundedRect(this->rect(), radius, radius); painter->restore();}void ProgressThree::drawValue1(QPainter *painter){ painter->save(); //计算百分比以及对应的宽度 int sum = value1 + value2 + value3; double percent = (double)value1 / sum; width1 = this->width() * percent; painter->setPen(Qt::NoPen); painter->setBrush(color1); //计算绘制的区域,需要裁剪圆角部分 QPainterPath clipPath; clipPath.addRoundedRect(this->rect(), radius, radius); painter->setClipPath(clipPath); QRect rect(0, 0, width1, this->height()); painter->drawRect(rect); //绘制文字 if (showValue) { //设置文字字体+颜色 if (autoFont) { QFont font; font.setPixelSize(this->height() * 0.9); painter->setFont(font); } QString text = QString::number(value1); if (showPercent) { text = QString("%1%").arg(QString::number(percent * 100, 'f', 0)); } painter->setPen(textColor); painter->drawText(rect, Qt::AlignCenter, text); } painter->restore();}void ProgressThree::drawValue2(QPainter *painter){ painter->save(); //计算百分比以及对应的宽度 int sum = value1 + value2 + value3; double percent = (double)value2 / sum; width2 = this->width() * percent; painter->setPen(Qt::NoPen); painter->setBrush(color2); //计算绘制的区域,需要裁剪圆角部分 QPainterPath clipPath; clipPath.addRoundedRect(this->rect(), radius, radius); painter->setClipPath(clipPath); QRect rect(width1, 0, width2, this->height()); painter->drawRect(rect); //绘制文字 if (showValue) { //设置文字字体+颜色 if (autoFont) { QFont font; font.setPixelSize(this->height() * 0.9); painter->setFont(font); } QString text = QString::number(value2); if (showPercent) { text = QString("%1%").arg(QString::number(percent * 100, 'f', 0)); } painter->setPen(textColor); painter->drawText(rect, Qt::AlignCenter, text); } painter->restore();}void ProgressThree::drawValue3(QPainter *painter){ painter->save(); //宽度减去其他两个就是 int sum = value1 + value2 + value3; double percent = (double)value3 / sum; width3 = this->width() - width1 - width2; painter->setPen(Qt::NoPen); painter->setBrush(color3); //计算绘制的区域,需要裁剪圆角部分 QPainterPath clipPath; clipPath.addRoundedRect(this->rect(), radius, radius); painter->setClipPath(clipPath); QRect rect(width1 + width2, 0, width3, this->height()); painter->drawRect(rect); //绘制文字 if (showValue) { //设置文字字体+颜色 if (autoFont) { QFont font; font.setPixelSize(this->height() * 0.9); painter->setFont(font); } QString text = QString::number(value3); if (showPercent) { text = QString("%1%").arg(QString::number(percent * 100, 'f', 0)); } painter->setPen(textColor); painter->drawText(rect, Qt::AlignCenter, text); } painter->restore();}void ProgressThree::drawBorder(QPainter *painter){ painter->save(); QPen pen; pen.setWidthF(borderWidth); pen.setColor(borderColor); painter->setPen(borderWidth > 0 ? pen : Qt::NoPen); painter->setBrush(Qt::NoBrush); int radius = this->radius; if (autoRadius) { radius = this->height() / 2; } //绘制圆角矩形 painter->drawRoundedRect(this->rect(), radius, radius); painter->restore();}
欢迎大家提出改进建议,谢谢!