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,+ -切换流动方法,定时器间隔设置流动速度。
仅供参考!
希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯分享时的吝啬。