Qt编写自定义控件:流程进度展示控件

代码:

#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 = &currentStepColor;
        }
        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();

这个控件的关键点在于确定下方文字的位置,要是位置设置不好上面的圆会和文字不协调。

绘制文字的位置在矩形的上方中央:

猜你喜欢

转载自blog.csdn.net/kenfan1647/article/details/121521957