Qt实现流动管道的一个思路

分为管道段Section和管道连接段Join两部分。
PipeSection使用drawLine绘制
PipeJoin使用drawArc绘制
都加入到path中去,最后调研drawPath来绘制

为了体现管道的立体性,定义管道的内壁宽度InnerLayerWidth和外壁宽度OutterLayerWidth。外壁用纯色填充,内壁用渐变色填充。

流动Flow:
定义好流动路径,将画笔宽适当调窄,设置合适的颜色,使用Dash模式线型来绘制流动路径,并通过定时器,动态改变DashOffset来模拟流动效果。

 

为简单模拟起见
使用较宽的QPen通过绘制Polyline来绘制管道,通过较窄Dash线的QPen来绘制液体流动。

Qt实现Pipe图形项:

#ifndef ITEMPOLYLINE_H
#define ITEMPOLYLINE_H

#include "ItemBase.h"

class ItemPolyline
        : public QObject
        , public ItemBase

{
    Q_OBJECT
public:
    ItemPolyline(QSize size, QGraphicsItem *parent = nullptr);
    virtual void paint(QPainter * painter,
                       const QStyleOptionGraphicsItem * option,
                       QWidget * widget = nullptr);
    // overwrite shape()
    QPainterPath shape() const;

private slots:
    void update1();

private:
    qreal m_offset;
};
#endif // ITEMPOLYLINE_H

 
#include "ItemPolyline.h"
#include <QPainter>
#include <QPainterPath>
#include <QTimer>


ItemPolyline::ItemPolyline(QSize size, QGraphicsItem *parent)
    : ItemBase (size, parent)
    , m_offset(0)
{
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update1()));
    timer->start(100);
}

void ItemPolyline::paint(QPainter *painter,
                         const QStyleOptionGraphicsItem *option,
                         QWidget *widget)
{
    static const QPointF points[3] = {
        QPointF(10.0, 300.0),
        QPointF(20.0, 10.0),
        QPointF(300.0, 30.0),
    };

    painter->save();
    QPen pen(Qt::gray);
    pen.setWidth(30);
    pen.setJoinStyle(Qt::RoundJoin);    // MiterJoin, BevelJoin, RoundJoin
    pen.setCapStyle(Qt::RoundCap);      // FlatCap, SquareCap, RoundCap
    pen.setStyle(Qt::SolidLine);
    painter->setPen(pen);
    painter->drawPolyline(points, 3);
    painter->restore();

    painter->save();
    QPen pen1(Qt::yellow);
    QVector<qreal> dashes;
    qreal space = 1;
    dashes << 2 << space << 2 << space;
    pen1.setDashPattern(dashes);
    pen1.setWidth(10);
    pen1.setJoinStyle(Qt::RoundJoin);    // MiterJoin, BevelJoin, RoundJoin
    pen1.setCapStyle(Qt::RoundCap);      // FlatCap, SquareCap, RoundCap
    pen1.setDashOffset(m_offset);
    painter->setPen(pen1);
    painter->drawPolyline(points, 3);
    painter->restore();

    ItemBase::paint(painter, option, widget);
}

QPainterPath ItemPolyline::shape() const
{
    static const QPointF points[3] = {
        QPointF(10.0, 300.0),
        QPointF(20.0, 10.0),
        QPointF(300.0, 30.0),
    };

    QPainterPath path;
    path.moveTo(points[0]);
    path.lineTo(points[1]);
    path.lineTo(points[2]);

    //return path;
    QPainterPathStroker stroker;
    stroker.setWidth(10);
    stroker.setJoinStyle(Qt::MiterJoin);
    stroker.setCapStyle(Qt::RoundCap);
    stroker.setDashPattern(Qt::DashLine);
    return stroker.createStroke(path);
}

void ItemPolyline::update1()
{
    m_offset += 0.5;
    update();
}

注意:DashOffset,+ -切换流动方法,定时器间隔设置流动速度。
仅供参考!

原文地址:https://www.cnblogs.com/MakeView660/p/12827166.html