效果:
代码:
#ifndef TIMELINECONTROLSWIDGET_H
#define TIMELINECONTROLSWIDGET_H
#include <QWidget>
#include <QDate>
class QPainter;
class TimelineControlsWidget : public QWidget
{
Q_OBJECT
public:
TimelineControlsWidget(QWidget *parent = nullptr);
~TimelineControlsWidget()override;
protected:
void paintEvent(QPaintEvent *event)override;
private:
void drawYearCircle(QPainter * painter, int x, int y);
void drawSmallCircle(QPainter * painter, int x, int y);
QList<std::pair<QDate,QString>> infoList;
};
#endif // TIMELINECONTROLSWIDGET_H
#include "timelinecontrolswidget.h"
#include <QPainter>
#include <QPaintEvent>
TimelineControlsWidget::TimelineControlsWidget(QWidget *parent)
: QWidget(parent)
{
setPalette(Qt::white);
infoList << std::make_pair<QDate,QString>(QDate(2021,10,1),"国庆节放假");
infoList << std::make_pair<QDate,QString>(QDate(2021,8,1),"建党百年,伟大征程");
infoList << std::make_pair<QDate,QString>(QDate(2021,5,1),"劳动节放假");
infoList << std::make_pair<QDate,QString>(QDate(2021,3,8),"妇女节,女士放假,男士未放假");
infoList << std::make_pair<QDate,QString>(QDate(2020,11,11),"购物节");
infoList << std::make_pair<QDate,QString>(QDate(2020,12,26),"圣诞节");
infoList << std::make_pair<QDate,QString>(QDate(2020,4,1),"愚人节");
infoList << std::make_pair<QDate,QString>(QDate(2020,1,20),"新冠疫情开始爆发");
infoList << std::make_pair<QDate,QString>(QDate(2019,10,1),"东风17、东风41亮相");
}
TimelineControlsWidget::~TimelineControlsWidget()
{
}
void TimelineControlsWidget::drawYearCircle(QPainter * painter,int x, int y)
{
auto radiu = 20;
QRect boundingRect = QRect(-radiu,-radiu,radiu * 2,radiu * 2);
painter->save();
painter->translate(x,y);
QLinearGradient linearGradient(boundingRect.topLeft(),boundingRect.bottomRight());
linearGradient.setColorAt(0.0,QColor("#7FDA8B"));
linearGradient.setColorAt(1.0,QColor("#17B721"));
// linearGradient.setColorAt(0.0,Qt::green);
// linearGradient.setColorAt(1.0,Qt::blue);
painter->setBrush(linearGradient);
painter->setPen(Qt::transparent);
painter->drawEllipse(boundingRect);
painter->setBrush(Qt::white);
painter->drawEllipse(boundingRect.adjusted(3,3,-3,-3));
painter->setPen(QPen(QBrush(linearGradient), 5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));//渐变线
painter->drawLine(QPoint(0,0),QPoint(0,-8));
painter->drawLine(QPoint(0,0),QPoint(8,0));
painter->restore();
}
void TimelineControlsWidget::drawSmallCircle(QPainter * painter, int x, int y)
{
auto radiu = 6;
QRect boundingRect = QRect(-radiu,-radiu,radiu * 2,radiu * 2);
painter->save();
painter->translate(x,y);
QLinearGradient linearGradient(boundingRect.topLeft(),boundingRect.bottomRight());
linearGradient.setColorAt(0.0,QColor("#7FDA8B"));
linearGradient.setColorAt(1.0,QColor("#17B721"));
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->restore();
}
void TimelineControlsWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
const auto rect = event->rect();
int drawCircleShapeX = static_cast<int>(rect.width() * 0.3);
painter.save();
QPen pen = painter.pen();
pen.setColor("#4CCB5E");
pen.setWidth(2);
painter.setPen(pen);
painter.drawLine(QPoint(drawCircleShapeX,0),QPoint(drawCircleShapeX,rect.height()));
painter.restore();
int y = 20;
int year{-1};
for(const auto & item : infoList)
{
if(item.first.year() != year)
{
y += 30;
year = item.first.year();
drawYearCircle(&painter,drawCircleShapeX,y);
painter.save();
auto font = painter.font();
font.setPixelSize(30);
font.setBold(true);
painter.setFont(font);
QRect yearTextRect(0,y-20,static_cast<int>(rect.width() * 0.25),40);
painter.drawText(yearTextRect,Qt::AlignRight | Qt::AlignVCenter,QString::number(year));
painter.restore();
y += 70;
}
drawSmallCircle(&painter,drawCircleShapeX,y);
{
painter.save();
auto font = painter.font();
font.setPixelSize(16);
painter.setFont(font);
QRect dayTextRect(0,y-20,static_cast<int>(rect.width() * 0.20),40);
painter.drawText(dayTextRect,Qt::AlignRight | Qt::AlignVCenter,
QString("%1").arg(QString::number(item.first.day()),2,QChar{'0'}));
painter.restore();
}
{
painter.save();
auto font = painter.font();
font.setPixelSize(12);
painter.setFont(font);
QRect monthTextRect(static_cast<int>(rect.width() * 0.20) + 10,y - 20,
static_cast<int>(rect.width() * 0.05),40);
painter.drawText(monthTextRect,Qt::AlignRight | Qt::AlignVCenter,
QString("%1月").arg(QString::number(item.first.month()),2,QChar{'0'}));
painter.restore();
}
{
painter.save();
auto font = painter.font();
font.setPixelSize(14);
painter.setFont(font);
QRect infoTextRect(drawCircleShapeX + 30,y-20,
static_cast<int>(rect.width() * 0.7 - 30),40);
painter.drawText(infoTextRect,Qt::AlignLeft | Qt::AlignVCenter,item.second);
painter.restore();
}
y += 40;
}
}