效果如图:
可设置:线条颜色,线条背景颜色,线条宽度,线条背景宽度,流速,流向
初始化时设置起始点跟结束点会判断是使用直线还是折线,折线分为两折线跟三折线(三折线需要设置)。
主要代码:
.h
public:
explicit wyPipeProgress(QWidget *parent = nullptr);
void setLineWidth(int width){lineWidth = width;}
void setBgLineWidth(int width){bgLineWidth = width;}
void setLineColor(QColor color){lineColor = color;}
void setBackgroundColor(QColor bgColor){backgroundColor = bgColor;}
void setDirect(bool directFlag){directionFlag = directFlag; }
void setPos(QPointF pos1, QPointF pos2){startPos = pos1;endPos = pos2;}
void setSpeed(int speed){fluidSpeed = speed;}
void setCapStyle(Qt::PenCapStyle style){capStyle = style;}
void setMulPolyLine(bool mulPolyLine){mulPolyLineFlag = mulPolyLine;} //设置是否为三折线,默认是两折线
void setMulPolyLineDirect(bool virticleFlag){mulPolyLineVirticleDirection = virticleFlag;} //设置三折线方向,横向还是竖向
int getLineWidth(){return lineWidth;}
int getBgLineWidth(){return bgLineWidth;}
QColor getLineColor(){return lineColor;}
QColor getBgColor(){return backgroundColor;}
bool getDirect(){return directionFlag;}
int getSpeed(){return fluidSpeed;}
Qt::PenCapStyle getCapStyle(){return capStyle;}
QPointF getPos1(){return startPos;}
QPointF getPos2(){return endPos;}
bool getMulPolyLineFlag(){return mulPolyLineFlag;}
bool getMulPolyLineDirect(){return mulPolyLineVirticleDirection;}
void drawPolyLineWith4Points(QPointF points[4]);
void run();
protected:
void paintEvent(QPaintEvent *event);
public slots:
void updateValue();
.cpp
void wyPipeProgress::paintEvent(QPaintEvent *)
{
// qInfo()<<"startX:"<<startPos.x()<<"startY:"<<startPos.y()<<"endX:"<<endPos.x()<<"endY:"<<endPos.y();
//根据起始点与终点判断是需要折线还是直线,亦或是三折线
if(startPos.x() == endPos.x() || startPos.y() == endPos.y()) //直线
{
QPainter painter(this);
// painter.setRenderHints(QPainter::Antialiasing);
QPen pen(backgroundColor);
pen.setJoinStyle(Qt::RoundJoin); // MiterJoin, BevelJoin, RoundJoin
pen.setStyle(Qt::SolidLine);
pen.setWidth(bgLineWidth);
pen.setCapStyle(capStyle); // FlatCap, SquareCap, RoundCap
painter.setPen(pen);
painter.drawLine(startPos, endPos);
// QPen pen1(lineColor);
QPen pen1(Qt::blue);
QVector<qreal> dashes;
qreal space = 2;
dashes << 3 << space << 3 << space;
pen1.setDashPattern(dashes);
pen1.setWidth(lineWidth);
pen1.setJoinStyle(Qt::RoundJoin); // MiterJoin, BevelJoin, RoundJoin
pen1.setCapStyle(capStyle); // FlatCap, SquareCap, RoundCap
pen1.setDashOffset(m_offset);
painter.setPen(pen1);
painter.drawLine(startPos, endPos);
}
else
{
if(!mulPolyLineFlag) //两折线
{
QPointF pos1 = startPos;
QPointF pos2(endPos.x(), startPos.y());
QPointF pos3 = endPos;
QPointF points[3] = {pos1,pos2,pos3};
QPainter painter(this);
// painter.setRenderHints(QPainter::Antialiasing);
QPen pen(backgroundColor);
pen.setJoinStyle(Qt::RoundJoin); // MiterJoin, BevelJoin, RoundJoin
pen.setStyle(Qt::SolidLine);
pen.setWidth(bgLineWidth);
pen.setCapStyle(capStyle); // FlatCap, SquareCap, RoundCap
painter.setPen(pen);
painter.drawPolyline(points, 3);
QPen pen1(lineColor);
QVector<qreal> dashes;
qreal space = 2;
dashes << 3 << space << 3 << space;
pen1.setDashPattern(dashes);
pen1.setWidth(lineWidth);
pen1.setJoinStyle(Qt::RoundJoin); // MiterJoin, BevelJoin, RoundJoin
pen1.setCapStyle(capStyle); // FlatCap, SquareCap, RoundCap
pen1.setDashOffset(m_offset);
painter.setPen(pen1);
painter.drawPolyline(points, 3);
}
else //三折线
{
if(mulPolyLineVirticleDirection) //垂直
{
QPointF pos1 = startPos;
QPointF pos2(startPos.x(), startPos.y() + (endPos.y() - startPos.y())/2);
QPointF pos3(endPos.x(), startPos.y() + (endPos.y() - startPos.y())/2);
QPointF pos4 = endPos;
QPointF points[4] = {pos1,pos2,pos3,pos4};
drawPolyLineWith4Points(points);
}
else //横向
{
QPointF pos1 = startPos;
QPointF pos2(startPos.x() + (endPos.x() - startPos.x())/2, startPos.y());
QPointF pos3(startPos.x() + (endPos.x() - startPos.x())/2, endPos.y());
QPointF pos4 = endPos;
QPointF points[4] = {pos1,pos2,pos3,pos4};
drawPolyLineWith4Points(points);
}
}
}
this->setFixedSize(this->window()->width(), this->window()->height());
}
wyPipeProgress::wyPipeProgress(QWidget *parent)
: QWidget(parent)
{
lineWidth = 5; //线条宽度
bgLineWidth =10; //背景线宽度
lineColor = Qt::red; //线条颜色
backgroundColor = Qt::gray; //背景线条颜色
directionFlag = true; //流动方向
// startPos = QPointF(0, 0);
// endPos = QPointF(0, 0); //起始点,结束点
fluidSpeed = 100; //流动速度
capStyle = Qt::RoundCap; //填充模式 FlatCap, SquareCap, RoundCap
mulPolyLineFlag = false;
mulPolyLineVirticleDirection = false; //默认横向
m_offset = 0;
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
// timer->start(fluidSpeed);
}
void wyPipeProgress::drawPolyLineWith4Points(QPointF points[4])
{
QPainter painter(this);
// painter.setRenderHints(QPainter::Antialiasing);
QPen pen(backgroundColor);
pen.setJoinStyle(Qt::RoundJoin); // MiterJoin, BevelJoin, RoundJoin
pen.setStyle(Qt::SolidLine);
pen.setWidth(bgLineWidth);
pen.setCapStyle(capStyle); // FlatCap, SquareCap, RoundCap
painter.setPen(pen);
painter.drawPolyline(points, 4);
QPen pen1(lineColor);
QVector<qreal> dashes;
qreal space = 2;
dashes << 3 << space << 3 << space;
pen1.setDashPattern(dashes);
pen1.setWidth(lineWidth);
pen1.setJoinStyle(Qt::RoundJoin); // MiterJoin, BevelJoin, RoundJoin
pen1.setCapStyle(capStyle); // FlatCap, SquareCap, RoundCap
pen1.setDashOffset(m_offset);
painter.setPen(pen1);
painter.drawPolyline(points, 4);
}
void wyPipeProgress::run()
{
// timer = new QTimer(this);
// connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
timer->start(fluidSpeed);
}
void wyPipeProgress::updateValue()
{
// qInfo()<<"111";
if(directionFlag)
{
m_offset += 0.5;
}
else
{
m_offset -= 0.5;
}
update();
}
调用方式:
pipe1 = new wyPipeProgress;
pipe1->setParent(ui->widget);
pipe2 = new wyPipeProgress;
pipe2->setParent(ui->widget);
pipe3 = new wyPipeProgress;
pipe3->setParent(ui->widget);
pipe4 = new wyPipeProgress;
pipe4->setParent(ui->widget);
pipe5 = new wyPipeProgress;
pipe5->setParent(ui->widget);
pipe6 = new wyPipeProgress;
pipe6->setParent(ui->widget);
pipe7 = new wyPipeProgress;
pipe7->setParent(ui->widget);
pipe8 = new wyPipeProgress;
pipe8->setParent(ui->widget);
pipe9 = new wyPipeProgress;
pipe9->setParent(ui->widget);
pipe10 = new wyPipeProgress;
pipe10->setParent(ui->widget);
pipe11 = new wyPipeProgress;
pipe11->setParent(ui->widget);
pipe12 = new wyPipeProgress;
pipe12->setParent(ui->widget);
//btn0-btn1
QPointF sBnt1Pos1((ui->btn0->geometry().x()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2)); //btn0左中点
QPointF sBnt1Pos3((ui->btn1->geometry().x() + ui->btn1->size().width()),
(ui->btn1->geometry().y() + ui->btn1->size().height()/2));
pipe1->setPos(sBnt1Pos1, sBnt1Pos3);
pipe1->setDirect(false);
// pipe1->setCapStyle(Qt::FlatCap);
pipe1->setLineColor(Qt::yellow);
pipe1->setBackgroundColor(Qt::green);
pipe1->run();
pipe1->lower();
// pipe1->raise();
//btn0-btn2
QPointF sBnt2Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()/2),
(ui->btn0->geometry().y())); //btn0上中
QPointF sBnt2Pos3((ui->btn2->geometry().x() + ui->btn2->size().width()/2),
(ui->btn2->geometry().y() + ui->btn2->size().height()));
pipe2->setPos(sBnt2Pos1, sBnt2Pos3);
pipe2->setDirect(false);
pipe2->run();
pipe2->lower();
// pipe2->raise();
//btn0-btn3
QPointF sBnt3Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2)); //右中
QPointF sBnt3Pos3((ui->btn3->geometry().x()),
(ui->btn3->geometry().y() + ui->btn3->size().height()/2));
pipe3->setPos(sBnt3Pos1, sBnt3Pos3);
pipe3->setDirect(false);
pipe3->run();
pipe3->lower();
// pipe3->raise();
//btn0-btn4
QPointF sBnt4Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()/2),
(ui->btn0->geometry().y() + ui->btn0->size().height())); //下中
QPointF sBnt4Pos3((ui->btn4->geometry().x() + ui->btn4->size().width()/2),
(ui->btn4->geometry().y()));
pipe4->setPos(sBnt4Pos1, sBnt4Pos3);
pipe4->setDirect(false);
pipe4->run();
pipe4->lower();
// pipe4->raise();
// btn0-btn5
QPointF sBnt5Pos1((ui->btn0->geometry().x()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt5Pos3((ui->btn5->geometry().x() + ui->btn5->size().width()/2),
(ui->btn5->geometry().y() + ui->btn5->size().height()));
pipe5->setPos(sBnt5Pos1, sBnt5Pos3);
pipe5->setDirect(false);
pipe5->run();
pipe5->lower();
// btn0-btn6
QPointF sBnt6Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt6Pos3((ui->btn6->geometry().x() + ui->btn6->size().width()/2),
(ui->btn6->geometry().y() + ui->btn6->size().height()));
pipe6->setPos(sBnt6Pos1, sBnt6Pos3);
pipe6->setDirect(false);
pipe6->run();
pipe6->lower();
// btn0-btn7
QPointF sBnt7Pos1((ui->btn0->geometry().x()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt7Pos3((ui->btn7->geometry().x() + ui->btn7->size().width()/2),
(ui->btn7->geometry().y()));
pipe7->setPos(sBnt7Pos1, sBnt7Pos3);
pipe7->setDirect(false);
pipe7->run();
pipe7->lower();
// // btn0-btn8
// QPointF sBnt8Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()),
// (ui->btn0->geometry().y() + ui->btn0->size().height()/2));
// QPointF sBnt8Pos3((ui->btn8->geometry().x() + ui->btn8->size().width()/2),
// (ui->btn8->geometry().y()));
// pipe8->setPos(sBnt8Pos1, sBnt8Pos3);
// pipe8->setDirect(false);
// pipe8->run();
// pipe8->lower();
// btn0-btn8 三折线 横向
QPointF sBnt8Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt8Pos3((ui->btn8->geometry().x()),
(ui->btn8->geometry().y() + ui->btn8->size().height()/2));
pipe8->setPos(sBnt8Pos1, sBnt8Pos3);
pipe8->setMulPolyLine(true);
pipe8->setMulPolyLineDirect(false);
pipe8->setDirect(false);
pipe8->run();
pipe8->lower();
// btn0-btn9
QPointF sBnt9Pos1((ui->btn0->geometry().x()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt9Pos3((ui->btn9->geometry().x() + ui->btn9->size().width()/2),
(ui->btn9->geometry().y() + ui->btn9->size().height()));
pipe9->setPos(sBnt9Pos1, sBnt9Pos3);
pipe9->setDirect(false);
pipe9->run();
pipe9->lower();
// // btn0-btn10
// QPointF sBnt10Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()),
// (ui->btn0->geometry().y() + ui->btn0->size().height()/2));
// QPointF sBnt10Pos3((ui->btn10->geometry().x() + ui->btn10->size().width()/2),
// (ui->btn10->geometry().y() + ui->btn10->size().height()));
// pipe10->setPos(sBnt10Pos1, sBnt10Pos3);
// pipe10->setDirect(false);
// pipe10->run();
// pipe10->lower();
// btn0-btn10 三折线 竖
QPointF sBnt10Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()/2),
(ui->btn0->geometry().y()));
QPointF sBnt10Pos3((ui->btn10->geometry().x() + ui->btn10->size().width()/2),
(ui->btn10->geometry().y() + ui->btn10->size().height()));
pipe10->setPos(sBnt10Pos1, sBnt10Pos3);
pipe10->setMulPolyLine(true);
pipe10->setMulPolyLineDirect(true);
pipe10->setDirect(false);
pipe10->run();
pipe10->lower();
// btn0-btn11
QPointF sBnt11Pos1((ui->btn0->geometry().x()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt11Pos3((ui->btn11->geometry().x() + ui->btn11->size().width()/2),
(ui->btn11->geometry().y()));
pipe11->setPos(sBnt11Pos1, sBnt11Pos3);
pipe11->setDirect(false);
pipe11->run();
pipe11->lower();
// btn0-btn12
QPointF sBnt12Pos1((ui->btn0->geometry().x() + ui->btn0->size().width()),
(ui->btn0->geometry().y() + ui->btn0->size().height()/2));
QPointF sBnt12Pos3((ui->btn12->geometry().x() + ui->btn12->size().width()/2),
(ui->btn12->geometry().y()));
pipe12->setPos(sBnt12Pos1, sBnt12Pos3);
pipe12->setDirect(false);
pipe12->run();
pipe12->lower();