代码:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
//流程进度展示控件
class ProcessProgressDisplayWidget : public QWidget
{
Q_OBJECT
public:
ProcessProgressDisplayWidget(QWidget *parent = nullptr);
~ProcessProgressDisplayWidget()override;
void setProcessList(const QStringList &value);
void setCurrentStep(int value);
protected:
void paintEvent(QPaintEvent *event)override;
private:
QStringList processList;
int currentStep{1};
QColor lineColor{"#C0C4CC"};
QColor stepsCompletedColor{"#41CD52"};//已完成步骤的颜色
QColor stepUncompleteColor{"#333333"};//未完成步骤的颜色
QColor currentStepColor{"#FC5531"};//当前步骤颜色
};
#endif // WIDGET_H
#include "processprogressdisplaywidget.h"
#include <QPainter>
#include <QPaintEvent>
#include <QDebug>
ProcessProgressDisplayWidget::ProcessProgressDisplayWidget(QWidget *parent)
: QWidget(parent)
{
setPalette(Qt::white);
}
ProcessProgressDisplayWidget::~ProcessProgressDisplayWidget()
{
}
void drawSmallCircle(QPainter * painter, int x, int y,int radius,const QColor & color,const QString & text)
{
QRect boundingRect = QRect(-radius,-radius,radius * 2,radius * 2);
painter->save();
painter->translate(x,y);
QLinearGradient linearGradient(boundingRect.topLeft(),boundingRect.bottomRight());
linearGradient.setColorAt(0.0,color);
linearGradient.setColorAt(1.0,color.lighter());
painter->setBrush(linearGradient);
painter->setPen(QPen(QBrush(linearGradient), 3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));//渐变线
painter->drawEllipse(boundingRect);
painter->setBrush(Qt::white);
painter->drawEllipse(boundingRect.adjusted(1,1,-1,-1));
painter->setPen(color);
painter->drawText(boundingRect,Qt::AlignCenter,text);
painter->restore();
}
void ProcessProgressDisplayWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
auto font = painter.font();
font.setPixelSize(20);
font.setBold(true);
painter.setFont(font);
auto rect = event->rect();
auto width = rect.width();
auto height = rect.height();
int lineY = static_cast<int>(height * 0.3) ;
int startX = 80;
int size = processList.size();
int radius = 20;
int spacerLenth = (width - 2 * startX - (radius * 2 * size)) / (size - 1);
for(int i = 0;i < size;++i)
{
int x = startX + radius + (spacerLenth * i) + (radius * 2 * i);
QColor * color;
if(i < (size - 1))
{
painter.save();
if(i < currentStep)
{
color = &stepsCompletedColor;
}
else
{
color = &lineColor;
}
painter.setPen(QPen(*color,3));
painter.drawLine(QPoint(x + radius,lineY),QPoint(x + radius + spacerLenth,lineY));
painter.restore();
}
if(i < currentStep)
{
color = &stepsCompletedColor;
}
else if(i == currentStep)
{
color = ¤tStepColor;
}
else
{
color = &stepUncompleteColor;
}
drawSmallCircle(&painter,x,lineY+1,radius,*color,QString::number(i+1));
int textRectW;
if(i == 0 || i == (size - 1))
{
textRectW = 2 * (startX - 20) + radius * 2;
}
else
{
textRectW = spacerLenth + radius * 2;
}
int rextRectX;
if(i == 0)
{
rextRectX = 20;
}
else if(i == (size - 1))
{
rextRectX = startX + i * (radius * 2) + spacerLenth * (i - 1) + (spacerLenth - (textRectW / 2) + radius);
}
else
{
rextRectX = startX + spacerLenth/2 + spacerLenth * (i - 1) + i * 2 * radius;
}
QRect textRect = QRect(rextRectX,
lineY + radius * 2,
textRectW,
height - lineY - radius * 2);
painter.setPen(*color);
painter.drawText(textRect,Qt::AlignTop | Qt::AlignHCenter,processList[i]);
}
}
//设置当前步骤
void ProcessProgressDisplayWidget::setCurrentStep(int value)
{
currentStep = value;
update();
}
void ProcessProgressDisplayWidget::setProcessList(const QStringList &value)
{
processList = value;
currentStep = 0;
update();
}
使用:
ProcessProgressDisplayWidget w;
w.setProcessList(QStringList()<<"确认订单信息"<<"提交订单"<<"订单完成"<<"商品评价"<<"追加评论");
w.setCurrentStep(2);
w.show();
这个控件的关键点在于确定下方文字的位置,要是位置设置不好上面的圆会和文字不协调。
绘制文字的位置在矩形的上方中央: