QT自定义控件之电气接线图(源码开源)

一、前言

在电力微网、储能、换电站这类工业监控场景中,经常需要绘制动态电气接线组态图:要展示母线、变压器、PCS、储能电池、换电站、电子公路等设备,还要实现线路通电闪烁、设备状态灯变色、开关通断、实时状态渲染。市面上成熟组态软件固然强大,但定制成本高、二次开发受限。

这次尝试选择 C++ / Qt + QPainter 绘制这套电气接线可视化面板。没有使用第三方组态控件,整套界面完全基于 Qt 框架 + QPainter 绘制,没有使用 QSS 动画、没有外部 UI 组件库。背景图+QPainter来实现效果。自由度极高,配合定时器驱动刷新,实现线路流光、状态灯红绿黄切换,完成微网系统电气接线图的实时可视化。

难点:大量离散图元管理、管线动画性能、坐标映射、设备状态与绘图解耦,既要保证画面工业严谨感,又要动态渲染流畅不卡顿。

二、作品展示

先来上作品进行展示:

开发的核心亮点:

1、纯 QPainter 原生绘制,零第三方组态组件

数据和渲染逻辑分离,每个设备抽象成结构体保存坐标、类型、运行状态,paintEvent 中遍历绘制,便于后续增删设备。

2、电力线路流光动画效果

通电线路实现光点流动动画效果。使用 QTimer 定时触发窗口重绘,维护线路上光点偏移量,在 paintEvent 中批量绘制流动光点;可实现动画逻辑与业务状态解耦,修改设备运行状态就可以直接改变线路渲染效果。

3、多状态图元渲染,状态实时映射画面

指示灯、开关、变压器节点支持多状态渲染:正常绿色、告警黄色,业务层更新设备状态数据,绘图层根据状态枚举自动切换画笔颜色、填充色,不用修改绘图代码。

4、工业风 UI 外壳封装

使用 QPainter 绘制整机面板外壳、铆钉、边框、右侧三色指示灯面板、标题栏 "电气接线图",还原真实工控屏幕质感。底层绘图区域和外壳装饰分层绘制,装饰层不干扰业务图元,方便后续复用外壳到其他监控画面。

5、架构利于扩展

设备、线路都使用数据驱动绘制。后期可以考虑直接对接后端实时数据,把真实微网遥信遥测数据灌入,直接变成真实项目监控界面。

三、实现流程

1、主窗口结构

主窗口MainWindow,右上角放置普通 QPushButton【开始】按钮;中心放置我们自定义的绘图控件CustomWidget(继承自QWidget)

复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_Timer = new QTimer(this);
    connect(m_Timer,SIGNAL(timeout()),this,SLOT(SlotTimer()));
    m_currentFlag = true;
}

2、核心代码

本期的核心代码主要在CustomWidget.cpp中

部分代码展示:

复制代码
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif
void rotateAndPaintRect(QPainter *painter, const QRectF &rect, int angle,bool isRound = false,int rx = 0,int ry = 0)
{
qreal cx = 0;
qreal cy = 0;
cx = rect.center().x();
cy = rect.center().y();
painter->save();
painter->translate(cx ,cy);
painter->rotate(angle);
QPointF drawOffset = rect.topLeft() - QPointF(cx,cy);
painter->drawRect(drawOffset.x(), drawOffset.y(), rect.width(), rect.height());
painter->restore();
}
void DrawText(QPainter &painter,const QRectF &rect,QString str,double angle,int size,QString fontFamily,int textAlignment)
{
QRectF rotatedRect(-rect.width()/2, -rect.height()/2, rect.width(), rect.height());
qreal cx = rect.x() + rect.width() / 2;
qreal cy = rect.y() + rect.height() / 2;
QFont font = QFont(fontFamily, size);
painter.setFont(font);
painter.save();
painter.translate(cx, cy);
painter.scale(1, -1);
painter.rotate(-angle);//旋转角度
painter.drawText(rotatedRect,textAlignment,str);
//恢复上面保存的状态
painter.restore();
}
void DrawImage(QPainter &painter, QImage &image, const QRectF &rect,double angle)
{
QRectF rotatedRect(-rect.width()/2, -rect.height()/2, rect.width(), rect.height());
painter.drawImage(rotatedRect, image);
}

四、源码开放

本期源码开放,有需要的朋友可以去下面位置找我~

QT自定义控件之电气接线图(源码开源)

相关推荐
阿俊-全栈开发4 小时前
LikeShop 单商户SaaS商城分销模块二开:佣金计算与结算逻辑实现
java·开发语言·微服务·likeshop·likeshop开源商城·likeshop多商户
m0_380743877 小时前
C++中的freopen的用法实例详解
开发语言·c++
Escalating_xu8 小时前
【Python】基础语法(1):常量、变量、类型、输入输出与运算符
开发语言·python
jimy18 小时前
polymorph.cpp里面的“析构函数、智能指针”问题
开发语言·c++
m0_380743878 小时前
PHP 8.3 缓存清除不生效怎么排查
开发语言·php
朝朝辞暮i9 小时前
C++ 第 6 课:switch —— 多状态选择
开发语言·c++·算法
小凡geo9 小时前
本地商家 GEO:用脚本一键生成 FAQPage 结构化数据,让 AI 切片更稳
开发语言·人工智能·python·microsoft·搜索引擎·ai
朝朝辞暮i9 小时前
C++ 第 4 课:if / else —— 让程序自己做决定
开发语言·c++
波力海苔夹心脆6759 小时前
C# 值类型与引用类型详解:存储位置、赋值机制、参数传递、相等比较、装箱拆箱与常见陷阱
开发语言·jvm·经验分享·笔记·c#·.net
m0_380743879 小时前
Qt中导航栏实现的详细指南
开发语言·c++