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,+ -切换流动方法,定时器间隔设置流动速度。
仅供参考!

posted on   我来乔23  阅读(3464)  评论(2编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示