分为管道段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,+ -切换流动方法,定时器间隔设置流动速度。
仅供参考!
来源:oschina
链接:https://my.oschina.net/u/4375750/blog/4267036