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,+ -切換流動方法,定時器間隔設置流動速度。
僅供參考!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM