optimize topology previewer

This commit is contained in:
baiYue 2026-03-02 20:15:22 +08:00
parent dff1792794
commit 32c9cdd152
53 changed files with 1762 additions and 1026 deletions

View File

@ -69,7 +69,8 @@ set(H_HEADER_FILES
common/include/compiler.hpp
common/include/export.hpp
common/include/operatingSystem.hpp
common/include/structDataSource.h
common/include/extraPropertyManager.h
)
set(CPP_SOURCE_FILES
source/main.cpp
@ -97,6 +98,8 @@ set(CPP_SOURCE_FILES
common/source/global.cpp
common/source/tools.cpp
common/source/baseProperty.cpp
common/source/structDataSource.cpp
common/source/extraPropertyManager.cpp
)
set(UI_FILES
ui/mainwindow.ui

View File

@ -10,7 +10,7 @@ Item {
//
property var value
property string fileFilter: "所有文件 (*.*)" //
property string fileFilter: "svg(*.svg)" //
property bool selectMultiple: false //
implicitHeight: fileBox.implicitHeight
@ -55,6 +55,8 @@ Item {
FileDialog {
id: fileDialog
modality: Qt.WindowModal //
options: FolderDialog.DontUseNativeDialog //
title: control.selectMultiple ? "选择多个文件" : "选择文件"
fileMode: control.selectMultiple ? FileDialog.OpenFiles : FileDialog.OpenFile

View File

@ -32,7 +32,8 @@ public:
QStringList getGrids() const;
QStringList getZones(const QString& grid = "") const;
QStringList getStations(const QString& grid = "", const QString& zone = "") const;
private:
QString removeSuffix(const QString& str); //移除最后一个下划线后的内容 (处理各种tag后缀)
private:
QMap<QString, ExtraProperty> m_props; // 内存缓存
};

View File

@ -1219,9 +1219,9 @@ struct itemPageInfo //page中保存的item信息(大小位置etc)
double dRotate = 0.0;
};
/*********************运行时************************/
struct monitorRelationSturctItem //监控关系结构item
struct RelationSturctItem //层级关系结构item
{
QString sVoltageLevel;
int nCategory; //类型 0设备1间隔
int nEquipType; //设备类别
QString sName; //名称
@ -1229,6 +1229,7 @@ struct monitorRelationSturctItem //监控关系结构item
QJsonObject toJson() const {
QJsonObject obj;
obj["sVoltageLevel"] = sVoltageLevel;
obj["nCategory"] = nCategory;
obj["nEquipType"] = nEquipType;
obj["sName"] = sName;
@ -1238,6 +1239,7 @@ struct monitorRelationSturctItem //监控关系结构item
// 从JSON对象解析
void fromJson(const QJsonObject& json) {
sVoltageLevel = json["sVoltageLevel"].toString();
nCategory = json["nCategory"].toInt();
nEquipType = json["nEquipType"].toInt();
sName = json["sName"].toString();
@ -1250,18 +1252,18 @@ struct monitorRelationSturctItem //监控关系结构item
}
// 重载相等运算符
bool operator==(const monitorRelationSturctItem& other) const {
bool operator==(const RelationSturctItem& other) const {
return uid == other.uid &&
sName == other.sName &&
nCategory == other.nCategory;
}
};
struct monitorRelationItem //监控关系item
struct RelationItem //层级关系item
{
monitorRelationSturctItem parent;
monitorRelationSturctItem item;
QList<monitorRelationSturctItem> subList;
RelationSturctItem parent;
RelationSturctItem item;
QList<RelationSturctItem> subList;
QJsonObject toJson() const {
QJsonObject obj;
@ -1288,7 +1290,7 @@ struct monitorRelationItem //监控关系item
subList.clear();
QJsonArray subArray = json["subList"].toArray();
for (const QJsonValue& subValue : subArray) {
monitorRelationSturctItem sub;
RelationSturctItem sub;
sub.fromJson(subValue.toObject());
subList.append(sub);
}
@ -1300,7 +1302,7 @@ struct monitorRelationItem //监控关系item
}
// 添加子项
void addSubItem(const monitorRelationSturctItem& subItem) {
void addSubItem(const RelationSturctItem& subItem) {
subList.append(subItem);
}
@ -1316,7 +1318,7 @@ struct monitorRelationItem //监控关系item
}
// 查找子项
monitorRelationSturctItem* findSubItem(const QUuid& subUid) {
RelationSturctItem* findSubItem(const QUuid& subUid) {
for (auto& sub : subList) {
if (sub.uid == subUid) {
return &sub;
@ -1326,6 +1328,8 @@ struct monitorRelationItem //监控关系item
}
};
/*********************运行时************************/
struct monitorItemAttributeInfo //单个监控item属性
{
QString sGroup; //所属组别

View File

@ -1,5 +1,5 @@
// extraPropertyManager.cpp
#include "instance/extraPropertyManager.h"
#include "extraPropertyManager.h"
#include "dataBase.h"
#include <QDebug>
@ -12,6 +12,7 @@ bool ExtraPropertyManager::loadAll() {
QList<ExtraProperty> lstPro = DataBase::GetInstance()->getAllExtraProperty();
for(auto& pro:lstPro){
pro.bay_tag = removeSuffix(pro.bay_tag);
m_props[pro.code] = pro;
count++;
}
@ -66,3 +67,11 @@ QStringList ExtraPropertyManager::getGrids() const {
}
return QStringList(grids.begin(), grids.end());
}
QString ExtraPropertyManager::removeSuffix(const QString& str)
{
int lastUnderscore = str.lastIndexOf('_');
if (lastUnderscore == -1) return str; // 没有下划线
return str.left(lastUnderscore);
}

View File

@ -43,7 +43,6 @@ set(DIAGRAMCAVAS_HEADER_FILES
include/diagramConnectSetting.h
include/structDataPreviewDlg.h
include/titleBar.h
include/structDataSource.h
include/structDataMeasurementModel.h
include/structDataPropertyModel.h
include/structDataMeasurementDelegate.h
@ -127,7 +126,6 @@ set(DIAGRAMCAVAS_HEADER_FILES
include/util/selectorManager.h
include/util/subMovingSelector.h
include/instance/dataAccessor.h
include/instance/extraPropertyManager.h
include/propertyType/CustomGadget.h
include/propertyType/CustomType.h
@ -142,6 +140,8 @@ set(DIAGRAMCAVAS_HEADER_FILES
../common/include/compiler.hpp
../common/include/export.hpp
../common/include/operatingSystem.hpp
../common/include/structDataSource.h
../common/include/extraPropertyManager.h
)
set(DIAGRAMCAVAS_SOURCE_FILES
@ -186,7 +186,6 @@ set(DIAGRAMCAVAS_SOURCE_FILES
source/diagramConnectSetting.cpp
source/structDataPreviewDlg.cpp
source/titleBar.cpp
source/structDataSource.cpp
source/structDataMeasurementModel.cpp
source/structDataPropertyModel.cpp
source/structDataMeasurementDelegate.cpp
@ -270,7 +269,6 @@ set(DIAGRAMCAVAS_SOURCE_FILES
source/util/selectorManager.cpp
source/util/subMovingSelector.cpp
source/instance/dataAccessor.cpp
source/instance/extraPropertyManager.cpp
source/propertyType/PropertyTypeCustomization_CustomType.cpp
source/propertyType/propertyTypeCustomization_DataSourceType.cpp
@ -279,6 +277,8 @@ set(DIAGRAMCAVAS_SOURCE_FILES
../common/source/baseProperty.cpp
../common/source/tools.cpp
../common/source/global.cpp
../common/source/structDataSource.cpp
../common/source/extraPropertyManager.cpp
)
set(UI_FILES

View File

@ -50,13 +50,13 @@ public:
QString getGenerateByPanel() {return _sGenerateByPanel;}
PowerEntity* getEntity() {return _pEntity;}
BasePannelPropertyProxy* getPropertyProxy(){return _pPropertyProxy;}
BasePannelPropertyProxy* getPropertyProxy();
signals:
void panelDelete(const QString&,int);
protected:
virtual void closeEvent(QCloseEvent *closeEvent) {};
protected:
BasePannelPropertyProxy* _pPropertyProxy; //属性页代理
QPointer<BasePannelPropertyProxy> _pPropertyProxy; //属性页代理
protected:
DesignerView* m_pGraphicsView;
DesignerScene* m_pGraphicsScene;

View File

@ -14,8 +14,6 @@ public:
Q_PROPERTY(QString Name READ getName WRITE setName)
Q_PROPERTY(QSize Size READ getSize WRITE setSize)
Q_PROPERTY(PannelColorGadget* Color READ getColorGadgetPtr WRITE setColorGadgetPtr)
//Q_PROPERTY(QColor BackColor READ getBackColor WRITE setBackColor)
//Q_PROPERTY(QColor GridColor READ getGridColor WRITE setGridColor)
public:
BasePannelPropertyProxy(BaseDrawingPanel*);
~BasePannelPropertyProxy();
@ -26,10 +24,6 @@ public:
virtual void setSize(QSize);
PannelColorGadget* getColorGadgetPtr(){return _pColorGadget;}
void setColorGadgetPtr(PannelColorGadget* p){_pColorGadget = p;}
// virtual QColor getBackColor() const;
// virtual void setBackColor(QColor);
// virtual QColor getGridColor() const;
// virtual void setGridColor(QColor);
protected:
BaseDrawingPanel* _pPanel;
PannelColorGadget* _pColorGadget;

View File

@ -58,7 +58,7 @@ private:
Ui::dataSourceDlg *ui;
QStandardItemModel* _treeModel;
QStandardItem* m_currentCategoryItem; //当前操作对象
ExtraPropertyManager* _pExtraProManager; //使用外部的manager
ExtraPropertyManager* _pExtraProManager;
StructDataSource* m_dataSource;
QListWidgetItem* _curProperty; //当前属性
QString m_targetPropertyCode; //打开的目标code

View File

@ -45,11 +45,12 @@ public:
public:
void initial();
signals:
void prepareUpdateItems(QList<monitorRelationItem>,bool refresh);
void prepareSelectItems(QList<monitorRelationItem>);
void prepareUpdateItems(QList<RelationItem>,bool refresh);
void prepareSelectItems(QList<RelationItem>);
void updateMonitorList(QString,QPair<QString,QUuid>,int nMode = 0); //0新增1删除
void createdMonitorItems(QList<monitorRelationItem>); //创建的监控中item个数
void createdMonitorItems(QList<RelationItem>); //创建的监控中item个数
void selectTarget(QObject*);
void prepareUpdateTopology(QList<RelationItem>,bool refresh); //更新层级数
public slots:
void onSignal_addDrawingPanel(PowerEntity* p,DiagramMode = DM_edit,QString parent = QString()); //parent:派生运行时的page
void onSignal_addGraphicsItem(modelStateInfo&);
@ -79,6 +80,9 @@ public slots:
void onSignal_openStructDataPreview(); //打开结构数据界面
void onCreateTestBaseModelDiagram(); //生成测试基模图
/****************************拓扑关系(层级关系)******************************/
void onSignal_updateTopology(QList<RelationItem>,bool); //更新拓扑列表
/******************************生成组态***********************************/
void onSignal_createEditPanel(QString,QUuid);
void onSignal_prepareOpenSetting(QString);
@ -91,11 +95,11 @@ public slots:
/*********************************间隔**************************************/
void onSignl_openCurrentBay();
/********************************运行时**********************************/
void onSignal_updateCurItems(QList<monitorRelationItem>,bool); //更新当前设备列表
void onSignal_selectedItems(QList<monitorRelationItem>); //当前选中设备
void onSignal_generate(QString,QList<monitorRelationItem>); //使用选中设备生成监控 (监控名,设备)
void onSignal_updateCurItems(QList<RelationItem>,bool); //更新当前设备列表
void onSignal_selectedItems(QList<RelationItem>); //当前选中设备
void onSignal_generate(QString,QList<RelationItem>); //使用选中设备生成监控 (监控名,设备)
void onSignal_monitorCreated(QString,QPair<QString,QUuid>); //监控已创建
void onSignal_monitorItemCreated(QList<monitorRelationItem>); //监控中创建的对象
void onSignal_monitorItemCreated(QList<RelationItem>); //监控中创建的对象
void onSignal_monitorSelected(DiagramInfo); //监控选中
void onSignal_saveMonitor(QList<QPair<QString,QUuid>>); //保存选中的监控

View File

@ -18,7 +18,7 @@ class DiagramEditorBayDetailSettingDlg : public QDialog
{
Q_OBJECT
public:
DiagramEditorBayDetailSettingDlg(QWidget *parent = nullptr);
DiagramEditorBayDetailSettingDlg(QWidget *parent = nullptr,DiagramEditorModel* p = nullptr);
~DiagramEditorBayDetailSettingDlg();
void initial();
@ -33,6 +33,7 @@ public:
DiagramEditorModel* getModel() {return _pModel;}
DiagramEditorBayBlock* getCurBlock(){return _curOperateObj;}
DiagramEditorWizard* getWizard() {return _pWizard;}
void showPreview(); //预览间隔
public slots:
void onAddClicked();
void onOkClicked();
@ -41,7 +42,6 @@ public slots:
void onRouteDeleteClicked();
void onRouteRbtnClicked(const QPoint &pos); //线路右键菜单
void onRouteEditClicked();
void onPreviewClicked(); //预览间隔
private:
Ui::diagramEditorBayDetailSettingDlg *ui;
DiagramEditorBayDetailAddDlg* _pAddDlg;

View File

@ -20,6 +20,7 @@ public:
void initial();
void showDlg(int nLayout); //0纵向1横向
void setParent(DiagramEditorBayDetailSettingDlg* p) {_pParent = p;}
void setSceneRect(const QRect);
//void updateModelData(); //根据设置更新data中布局、方向
private:
EditView* _pView;

View File

@ -19,7 +19,7 @@ class DiagramEditorTransDetailSettingDlg : public QDialog
{
Q_OBJECT
public:
DiagramEditorTransDetailSettingDlg(QWidget *parent = nullptr);
DiagramEditorTransDetailSettingDlg(QWidget *parent = nullptr,DiagramEditorModel* p = nullptr);
~DiagramEditorTransDetailSettingDlg();
void initial();
@ -36,6 +36,7 @@ public:
DiagramEditorModel* getModel() {return _pModel;}
DiagramEditorTransformerBlock* getCurBlock(){return _curOperateObj;}
DiagramEditorWizard* getWizard() {return _pWizard;}
void showPreview();
public slots:
void onAddClicked();
void onOkClicked();
@ -44,8 +45,6 @@ public slots:
void onRouteDeleteClicked();
void onRouteRbtnClicked(const QPoint &pos); //线路右键菜单
void onRouteEditClicked();
void onPreviewNeutralClicked(); //中性点成套装置预览
void onPreviewTransClicked(); //预览变压器
private:
Ui::diagramEditorTransDetailSettingDlg *ui;
DiagramEditorTransDetailAddDlg* _pAddDlg;

View File

@ -21,6 +21,7 @@ public:
void showDlg(int nType); //显示模式,0高压侧1中压侧2低压侧3变压器
void setParent(DiagramEditorTransDetailSettingDlg* p) {_pParent = p;}
void updateModelData(int showType); //根据设置更新data中布局、方向0变压器1高压侧2中压侧3低压侧
void setSceneRect(const QRect rec);
private:
EditView* _pView;
EditPreviewScene* _pScene;

View File

@ -39,9 +39,9 @@ public:
EditPanel* getPanel(){return _pPanel;}
void setWizard(QPointer<DiagramEditorWizard> p){_pWizard = p;}
QMap<QUuid,GraphicsBaseModelItem*> getPreviewItem(){return _previewItem;};
void clearItems(){_previewItem.clear();}
void clearItems();
void generatePreview(); //生成预览
void generatePreview(bool bVisible = true); //生成预览
void calculateBlockPos(); //重新计算block位置
void setItemInBlockPos(); //设置block中的item位置
void refreshConnection(); //刷新连接线
@ -56,6 +56,7 @@ public:
void setCurTransComponentModel(QStandardItemModel* p) {_pCurTransComponent = p;}
QStandardItemModel* setCurTransComponentModel() {return _pCurTransComponent;}
void setCurPreviewScene(EditBaseScene* p) {_pCurPreviewScene = p;}
EditBaseScene* getCurPreviewScene(){return _pCurPreviewScene;}
QStandardItem* getNameItem(const QString&,int nFrom = 0); //获取返回当前设备模型中的name项 nFrom,0间隔1变压器
void generateItemByModel(QStandardItemModel* pModel,DiagramEditorBaseBlock* pBlock,int nFrom = 0,QPoint delta = QPoint(0,0)); //0间隔1变压器
@ -68,7 +69,8 @@ public:
QByteArray getWizardInfo(); //返回二进制wizard设置
void setWizardInfo(const QByteArray&); //二进制设置wizard
signals:
void updateTopologyItems(QList<RelationItem>,bool); //更新当前拓扑列表 <连接关系,是否刷新>
private:
void bulidAndLinkComponent(QList<DiagramEditorComponentInfo>,QMap<QString,DiagramEditorComponentInfo>,DiagramEditorBaseBlock* pParent = nullptr); //生成并连接线路上的设备 lstmapComponents(从map中获取正确数据)
QByteArray serializeWizardData(const DiagramEditorProjectInfo &data); //序列化eidtor向导设置数据

View File

@ -105,12 +105,12 @@ public:
QJsonObject turnListToJson(QList<QUuid> lst,QString sInerTag,QString sOutTag); //将list转换为QJsonObject,<lst,内部标签,外部标签>
QList<QUuid> turnJsonArrToList(QJsonObject obj,QString sInner,QString sOut);
/*************************监控(运行时)**************************/
void generateMonitor(QString,QList<monitorRelationItem>); //生成监控 (监控名,选中的设备列表)
void generateMonitor(QString,QList<RelationItem>); //生成监控 (监控名,选中的设备列表)
void generateMonitorConfig(MonitorPanel*); //生成监控配置参数结构
void setMonitorPara(QMap<QUuid,QList<monitorItemAttributeInfo>> map){m_monitorPara = map;}
QMap<QUuid,QList<monitorItemAttributeInfo>>& getMonitorPara() {return m_monitorPara;}
void setMonitorRelation(QList<monitorRelationItem> lst){m_lstMonitorRelation = lst;}
QList<monitorRelationItem> getMonitorRelation() {return m_lstMonitorRelation;}
void setMonitorRelation(QList<RelationItem> lst){m_lstMonitorRelation = lst;}
QList<RelationItem> getMonitorRelation() {return m_lstMonitorRelation;}
void monitorItemSelected(QUuid); //运行时item选中事件
void monitorItemDetailAttr(QUuid); //显示属性详情
@ -130,11 +130,12 @@ public:
ItemPropertyDlg* getCurItemPropertyDlg() {return m_curPropertyDlg;}
Q_SIGNALS:
void activatePage(const QString&); //激活当前model所在page
void updateCurrentItems(QList<monitorRelationItem>,bool); //更新当前组态元件列表 <名称,uid>
void itemSelected(QList<monitorRelationItem>); //发送选中的元件
void updateCurrentItems(QList<RelationItem>,bool); //更新当前组态元件列表 <连接关系,是否刷新>
void itemSelected(QList<RelationItem>); //发送选中的元件
void monitorCreated(QString,QPair<QString,QUuid>); //监控创建信号 <工程page,<监控page,page_uid>>
void monitorItems(QList<monitorRelationItem>); //发送创建成功的Items
void monitorItems(QList<RelationItem>); //发送创建成功的Items
void dataUpdated(); //数据更新通知
void updateTopologyItems(QList<RelationItem>,bool); //更新当前拓扑列表 <连接关系,是否刷新>
public:
void setPageName(QString s) {_pageName = s;} //设置表名称
QString pageName() const {return _pageName;}
@ -186,7 +187,7 @@ private:
QMap<QUuid,QList<monitorItemAttributeInfo>> m_monitorPara; //监控参数
QMap<int,QList<QPair<monitorItemState,QString>>> m_monitorStateMap; //元件状态对照表 <type,<state,状态名>>
QMap<monitorItemTypeStruct,QMap<monitorItemStateStruct,monitorItemDisplayInfo>> m_monitorDisplaySetting; //元件设置
QList<monitorRelationItem> m_lstMonitorRelation; //监控item层级关系
QList<RelationItem> m_lstMonitorRelation; //监控item层级关系
ItemPropertyDlg* m_curPropertyDlg;
QTimer* m_dataTimer; //获取数据的定时器

View File

@ -7,6 +7,14 @@
class ElectricConnectLineItem : public GraphicsProjectModelItem
{
public:
enum UShapeType {
UShape_Unknown,
UShape_TopOpen, // 开口向上
UShape_BottomOpen, // 开口向下
UShape_LeftOpen, // 开口向左
UShape_RightOpen // 开口向右
};
public:
ElectricConnectLineItem(QGraphicsItem *parent = 0);
ElectricConnectLineItem(const ElectricConnectLineItem&); //暂不拷贝位置关系,由线自己计算
@ -17,12 +25,27 @@ public:
void setEndPoint(const QPointF& p);
QPainterPath getPoints(void) const { return m_points; }
void moveLine(QPointF); //鼠标点击拖动
void startDrag(const QPointF& scenePos);
void updateDrag(const QPointF& scenePos);
void endDrag();
void setLastPoint(const QPointF& point);
void setPath(const QPainterPath& path);
QPainterPath path() const;
void resetCurLine(){_curLine = QPoint();}
void calculatePath();
virtual QPainterPath shape() const override;
virtual QRectF boundingRect() const override;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
protected:
void initial();
private:
//路径计算相关
void generateAvoidancePath(const QPointF& start, const QPointF& end,const QList<QRectF>& obstacleShapes); // 使用形状进行避障
double calculatePathLength(const QList<QPointF>& path);
bool lineIntersectsRect(const QLineF& line, const QRectF& rect);
bool lineIntersectsRect(const QLineF& line, const QRectF& rect) const;
bool isSegmentSafe(const QPointF& p1, const QPointF& p2,const QList<QRectF>& components);
bool isPathSafe(const QList<QPointF>& path,const QList<QRectF>& components);
bool segmentPenetratesComponent(const QLineF& segment,const QRectF& component);
@ -33,18 +56,42 @@ public:
void generateForcedRectilinearBypass(const QPointF& start, const QPointF& end,const QList<QRectF>& components);
QRectF findFirstBlockingComponent(const QPointF& start, const QPointF& end,const QList<QRectF>& components);
virtual QPainterPath shape() const override;
virtual QRectF boundingRect() const override;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
//线段拖拽相关
double distancePointToLine(const QLineF& line, const QPointF& point) const;
void ensureEnoughPointsForDrag();
void debugPathState(const QString& context) const;
QVector<QLineF> extractSegmentsFromPainterPath() const;
void collectBoundaryBypassPaths(const QPointF& start, const QPointF& end,const QList<QRectF>& obstacles,QMultiMap<double, QList<QPointF>>& paths);
void collectBoundaryPath(const QPointF& start, const QPointF& end,const QList<QRectF>& obstacles,QMultiMap<double, QList<QPointF>>& paths,const QRectF& bounds, bool useTop);
QRectF getSceneBounds() const;
QList<QPointF> generateForcedBypass(const QPointF& start, const QPointF& end,const QList<QRectF>& components);
// 拖拽实现
int findSegmentAt(const QList<QPointF>& points,const QPointF& itemPos) const;
double distanceToSegment(const QLineF& segment, const QPointF& point) const;
void fixConnections(int segmentIndex, bool isVertical);
QList<QPointF> extractPointsFromPath() const;
QList<QPointF> extractPointsFromPath(const QPainterPath& path) const;
void applyPointsToPath(const QList<QPointF>& points);
void fixConnections(QList<QPointF>& points, int segmentIndex, bool isVertical);
void validateAndFixPath();
void updateBoundingRect();
protected:
void initial();
private:
QPainterPath m_points;
QPainterPath m_pointsBoundingRect; //包裹点的矩形集合
QList<QPointF> m_lstPoints;
QPoint _curLine; //参数1用点序号表示的当前线段起始点,参数2表示线段方向
struct DragState {
bool isActive = false;
int segmentIndex = -1;
bool isVertical = false;
QPointF startScenePos;
QPainterPath originalPath;
};
DragState m_dragData;
};
#endif

View File

@ -184,7 +184,7 @@ public:
Q_ENUM(RotateAngle);
Q_PROPERTY(QString Name READ getName WRITE setName)
Q_PROPERTY(QPointF Position READ getPosition WRITE setPosition)
Q_PROPERTY(QPointF Position READ getPosition WRITE setPosition NOTIFY posChanged)
Q_PROPERTY(QRectF Size READ getSize WRITE setSize)
Q_PROPERTY(RotateAngle Rotation READ getRotateAngle WRITE setRotateAngle)
Q_PROPERTY(QFileInfo Image READ getImage_1 WRITE setImage_1)
@ -195,6 +195,7 @@ public:
virtual GraphicsBaseItem* clone() const = 0;
signals:
void itemRotated(GraphicsBaseItem*);
void posChanged();
public:
virtual QString getName() const;
virtual void setName(QString);
@ -522,7 +523,7 @@ public slots:
void onUpdateData(); //data发送的更新通知
protected:
void rearrangeDynamicText(); //重新设置动态数据的布局
QList<QRectF> getComponentCollisionRects() const; //获取图所有碰撞矩形
QList<QRectF> getAllComponentRects() const; //获取图所有碰撞矩形
QList<QPainterPath> getObstacleShapes() const; //获取所有碰撞shape
protected:
FixedPortsModel* _pHandle;

View File

@ -26,7 +26,7 @@ public:
void setParentPage(const QString& str) {_sParentPage = str;}
QString getParentPage() {return _sParentPage;}
void updateSelectedItems(QList<monitorRelationItem>,bool);
void updateSelectedItems(QList<RelationItem>,bool);
QStandardItemModel* getLstModel() {return _itemListmodel;}
void initMonitorConfig(); //初始化参数设置(每个运行时可能不同)
@ -39,8 +39,8 @@ public:
MonitorConfigDlg* getMonitorConfigDlg() {return _pConfigDlg;}
public:
//对层级关系的序列化与反序列化
QJsonArray serializeRelationToJsonArray(const QList<monitorRelationItem>& data) const;
bool deserializeRelationFromJsonArray(const QJsonArray& jsonArray, QList<monitorRelationItem>& result);
QJsonArray serializeRelationToJsonArray(const QList<RelationItem>& data) const;
bool deserializeRelationFromJsonArray(const QJsonArray& jsonArray, QList<RelationItem>& result);
//对para的序列化与反序列化
QJsonArray serializeParaToJsonArray(const QMap<QUuid, QList<monitorItemAttributeInfo>>& data) const;
bool deserializeParaFromJsonArray(const QJsonArray& jsonArray,QMap<QUuid, QList<monitorItemAttributeInfo>>& result);

View File

@ -5,7 +5,7 @@
#include <QTreeView>
#include <QStandardItemModel>
struct monitorRelationItem;
struct RelationItem;
class MonitorSideBarDlg;
class QVBoxLayout;

View File

@ -20,7 +20,6 @@ BaseDrawingPanel::BaseDrawingPanel(PowerEntity* pEntity,QWidget *parent,DiagramM
,_verticalLayout(nullptr)
,_horizontalLayout(nullptr)
,_hSplitter(nullptr)
,_pPropertyProxy(nullptr)
{
_pEntity = pEntity;
_pModel = new FixedPortsModel(pEntity);
@ -66,8 +65,6 @@ BaseDrawingPanel::~BaseDrawingPanel()
{
//if(_pModel)
// delete _pModel;
if(_pPropertyProxy)
delete _pPropertyProxy;
}
QGraphicsScene* BaseDrawingPanel::getQGraphicsScene()
@ -80,6 +77,11 @@ DesignerScene* BaseDrawingPanel::getDesignerScene()
return m_pGraphicsScene;
}
BasePannelPropertyProxy* BaseDrawingPanel::getPropertyProxy()
{
return _pPropertyProxy.data();
}
SelectorManager* BaseDrawingPanel::selectorManager() const
{
if(m_pSelectorManager)

View File

@ -61,7 +61,8 @@ QMap<QString,propertyStateInfo> BaseInfoDlg::getPropertyValue(BaseProperty* pPro
if(pPro)
{
pPro->setTag(ui->le_tag->text());
pPro->setPath(ui->le_nameSpace->text());
if(!ui->le_nameSpace->text().isEmpty())
pPro->setPath(ui->le_nameSpace->text());
pPro->setName(ui->le_name->text());
pPro->setLabel(QJsonObject());
pPro->setDescription(ui->le_description->text());
@ -91,7 +92,7 @@ void BaseInfoDlg::setPropertyValue(QVariant var)
{
ui->le_uuid->setText(pPro->uuid().toString());
ui->le_tag->setText(pPro->tag());
ui->le_nameSpace->setText(pPro->path());
ui->le_nameSpace->setText(pPro->getBay());
ui->le_name->setText(pPro->name());
ui->le_label->setText(""); //label josn格式暂不解析
ui->le_description->setText(pPro->description());

View File

@ -36,23 +36,3 @@ void BasePannelPropertyProxy::setSize(QSize size)
{
_pPanel->resize(size);
}
/*QColor BasePannelPropertyProxy::getBackColor() const
{
return _pPanel->getScene()->getBackGoundColor();
}
void BasePannelPropertyProxy::setBackColor(QColor color)
{
_pPanel->getScene()->setBackGoundColor(color);
}
QColor BasePannelPropertyProxy::getGridColor() const
{
return _pPanel->getScene()->getGridColor();
}
void BasePannelPropertyProxy::setGridColor(QColor color)
{
_pPanel->getScene()->setGridColor(color);
}*/

View File

@ -3,7 +3,7 @@
#include <QStandardItemModel>
#include <QStack>
#include "structDataSource.h"
#include "instance/extraPropertyManager.h"
#include "extraPropertyManager.h"
#include "propertyType/dataSourceType.h"
#include <QTimer>
#include "global.h"

View File

@ -26,7 +26,7 @@
#include "itemPropertyDlg.h"
#include "monitorConfigDlg.h"
#include "structDataPreviewDlg.h"
#include "instance/extraPropertyManager.h"
#include "extraPropertyManager.h"
#include "QQuickDetailsViewMananger.h"
#include "propertyType/propertyTypeCustomization_DataSourceType.h"
@ -46,7 +46,7 @@ DiagramCavas::DiagramCavas(QWidget *parent)
DiagramCavas::~DiagramCavas()
{
disconnect(); //断开连接避免动态库释放时信号问题
}
DrawingPanel* DiagramCavas::getPanel(QString sPage)
@ -196,6 +196,7 @@ void DiagramCavas::onSignal_addDrawingPanel(PowerEntity* pItem,DiagramMode mode,
pModel->setCavas(QPointer<DiagramCavas>(this));
connect(pModel,&FixedPortsModel::activatePage,this,&DiagramCavas::onSignal_activatePage);
connect(pModel,&FixedPortsModel::updateCurrentItems,this,&DiagramCavas::onSignal_updateCurItems);
connect(pModel,&FixedPortsModel::updateTopologyItems,this,&DiagramCavas::onSignal_updateTopology);
connect(pModel,&FixedPortsModel::itemSelected,this,&DiagramCavas::onSignal_selectedItems);
connect(pPanel,&DrawingPanel::panelDelete,this,&DiagramCavas::onSignal_panelDelete);
}
@ -606,6 +607,12 @@ void DiagramCavas::onTargetSelected(QObject* obj)
if(obj)
emit selectTarget(obj);
}
/****************************************************/
void DiagramCavas::onSignal_updateTopology(QList<RelationItem> lst,bool refresh)
{
emit prepareUpdateTopology(lst,refresh);
}
/*******************************************************/
@ -650,7 +657,11 @@ EditPanel* DiagramCavas::onSignal_addEditPanel(QString sName)
_curPage = sName;
pPanel->setWindowTitle(_curPage);
pPanel->setCavas(this);
DiagramEditorModel* pModel = pPanel->getModel();
connect(pPanel,&EditPanel::panelDelete,this,&DiagramCavas::onSignal_panelDelete);
if(pModel){
connect(pModel,&DiagramEditorModel::updateTopologyItems,this,&DiagramCavas::onSignal_updateTopology);
}
QMdiSubWindow* pSub = this->addSubWindow(pPanel);
m_mapEditPanel.insert(_curPage,qMakePair(pPanel,pSub));
@ -721,17 +732,17 @@ void DiagramCavas::onSignl_openCurrentBay()
}
}
/*********************monitor**************************/
void DiagramCavas::onSignal_updateCurItems(QList<monitorRelationItem> lst,bool refresh)
void DiagramCavas::onSignal_updateCurItems(QList<RelationItem> lst,bool refresh)
{
emit prepareUpdateItems(lst,refresh);
}
void DiagramCavas::onSignal_selectedItems(QList<monitorRelationItem> lst)
void DiagramCavas::onSignal_selectedItems(QList<RelationItem> lst)
{
emit prepareSelectItems(lst);
}
void DiagramCavas::onSignal_generate(QString sPage,QList<monitorRelationItem> lst)
void DiagramCavas::onSignal_generate(QString sPage,QList<RelationItem> lst)
{
QWidget* pWindow= currentSubWindow()->widget();
DrawingPanel* pPanel = dynamic_cast<DrawingPanel*>(pWindow);
@ -745,7 +756,7 @@ void DiagramCavas::onSignal_monitorCreated(QString sProj,QPair<QString,QUuid> pa
emit updateMonitorList(sProj,pair);
}
void DiagramCavas::onSignal_monitorItemCreated(QList<monitorRelationItem> lst)
void DiagramCavas::onSignal_monitorItemCreated(QList<RelationItem> lst)
{
emit createdMonitorItems(lst);
}

View File

@ -482,6 +482,9 @@ void DiagramEditorBayDetailAddDlg::onOkClicked()
}
}
}
if(_pParent){
_pParent->showPreview();
}
hide();
}

View File

@ -9,7 +9,7 @@
#include "graphicsDataModel/diagramEditorModel.h"
#include "topologyManager.h"
DiagramEditorBayDetailSettingDlg::DiagramEditorBayDetailSettingDlg(QWidget *parent)
DiagramEditorBayDetailSettingDlg::DiagramEditorBayDetailSettingDlg(QWidget *parent,DiagramEditorModel* pModel)
: QDialog(parent)
, ui(new Ui::diagramEditorBayDetailSettingDlg)
,_pAddDlg(nullptr)
@ -17,7 +17,7 @@ DiagramEditorBayDetailSettingDlg::DiagramEditorBayDetailSettingDlg(QWidget *pare
,_compoModel(nullptr)
,_routeModel(nullptr)
,_pPreviewDlg(nullptr)
,_pModel(nullptr)
,_pModel(pModel)
,_pWizard(nullptr)
{
ui->setupUi(this);
@ -41,7 +41,6 @@ void DiagramEditorBayDetailSettingDlg::initial()
connect(ui->btn_add,&QPushButton::clicked,this,&DiagramEditorBayDetailSettingDlg::onAddClicked);
connect(ui->btn_ok,&QPushButton::clicked,this,&DiagramEditorBayDetailSettingDlg::onOkClicked);
connect(ui->btn_cancel,&QPushButton::clicked,this,&DiagramEditorBayDetailSettingDlg::onCancelClicked);
connect(ui->btn_preview,&QPushButton::clicked,this,&DiagramEditorBayDetailSettingDlg::onPreviewClicked);
connect(ui->tableView, &QTableView::customContextMenuRequested, this, &DiagramEditorBayDetailSettingDlg::onRouteRbtnClicked);
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
@ -52,6 +51,19 @@ void DiagramEditorBayDetailSettingDlg::initial()
ui->cb_layout->addItem("纵向",0);
ui->cb_layout->addItem("横向",1);
if(_pPreviewDlg == nullptr){
_pPreviewDlg = new DiagramEditorBayPreviewDlg(this);
_pPreviewDlg->setParent(this);
if(_pModel){
_pModel->setCurBayComponentModel(_compoModel);
_pModel->setCurBayRouteModel(_routeModel);
}
_pPreviewDlg->setSceneRect(ui->tableView->rect());
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(_pPreviewDlg);
ui->groupBox_preview->setLayout(layout);
}
}
void DiagramEditorBayDetailSettingDlg::refreshModel()
@ -270,6 +282,10 @@ void DiagramEditorBayDetailSettingDlg::onOkClicked()
}
hide();
_pModel->clearCurPreview(); //关闭时清除预览Item
_pModel->generatePreview();
_pModel->calculateBlockPos();
_pModel->setItemInBlockPos();
_pModel->refreshConnection();
//todo:清除mainPanel中的对应item(如果存在)
}
@ -361,22 +377,12 @@ void DiagramEditorBayDetailSettingDlg::onRouteEditClicked()
_pAddDlg->showDlg(routeInfo);
}
void DiagramEditorBayDetailSettingDlg::onPreviewClicked()
void DiagramEditorBayDetailSettingDlg::showPreview()
{
int nLayout = ui->cb_layout->currentData().toInt();
if(_pPreviewDlg == nullptr){
_pPreviewDlg = new DiagramEditorBayPreviewDlg(this);
_pPreviewDlg->setParent(this);
_pModel->setCurBayComponentModel(_compoModel);
_pModel->setCurBayRouteModel(_routeModel);
_pPreviewDlg->showDlg(nLayout);
QRectF recContainAll = _pModel->generateTempBay(_curOperateObj);
if(_curOperateObj){
_curOperateObj->setRecSize(recContainAll);
}
if(!_pPreviewDlg->isVisible()){
_pPreviewDlg->showDlg(nLayout);
QRectF recContainAll = _pModel->generateTempBay(_curOperateObj);
if(_curOperateObj){
_curOperateObj->setRecSize(recContainAll);
}
}
else
_pPreviewDlg->hide();
}

View File

@ -12,6 +12,7 @@ DiagramEditorBayPreviewDlg::DiagramEditorBayPreviewDlg(QWidget *parent)
,_pMainLayout(nullptr)
,_pParent(nullptr)
{
this->setWindowFlags(Qt::FramelessWindowHint | windowFlags());
QRect recParent = parent->geometry();
setGeometry(recParent.right(),recParent.y(),recParent.width(),recParent.height());
initial();
@ -26,9 +27,10 @@ void DiagramEditorBayPreviewDlg::initial()
{
_pMainLayout = new QVBoxLayout(this);
_pView = new EditView(this);
_pView->scale(0.5,0.5); //缩放为一半
_pMainLayout->addWidget(_pView);
_pScene = new EditPreviewScene(this);
_pScene->setSceneRect(-g_dGriaphicsScene_Width / 2, -g_dGriaphicsScene_Height / 2, g_dGriaphicsScene_Width, g_dGriaphicsScene_Height);
_pScene->setSceneRect(-g_dGriaphicsScene_Width / 2, -g_dGriaphicsScene_Height / 2, g_dGriaphicsScene_Width, g_dGriaphicsScene_Height); //初始大小
_pView->setScene(_pScene);
}
@ -37,7 +39,7 @@ void DiagramEditorBayPreviewDlg::showDlg(int nLayout)
if(_pParent){
_pParent->getModel()->setCurPreviewScene(_pScene);
}
show();
//show();
int nDir = 0;
if(nLayout == 0){ //纵,下右
nDir = 41;
@ -49,3 +51,8 @@ void DiagramEditorBayPreviewDlg::showDlg(int nLayout)
_pParent->getModel()->updateTarget(_pParent->getBayInfo().mapRoute,_pParent->getBayInfo().mapComponent,nDir,0);
}
void DiagramEditorBayPreviewDlg::setSceneRect(const QRect rec)
{
if(_pScene)
_pScene->setSceneRect(-rec.width()*0.5,-rec.height()*0.5,rec.width(),rec.height());
}

View File

@ -4,6 +4,8 @@
#include "graphicsDataModel/diagramEditorModel.h"
#include "diagramEditor/editPanel.h"
#include "global.h"
#include <QGuiApplication>
#include <QScreen>
DiagramEditorPreviewDlg::DiagramEditorPreviewDlg(QWidget *parent)
: QDialog(parent)
@ -12,6 +14,7 @@ DiagramEditorPreviewDlg::DiagramEditorPreviewDlg(QWidget *parent)
,_pMainLayout(nullptr)
,_pParent(nullptr)
{
setWindowTitle("预览");
auto pParent = dynamic_cast<EditPanel*>(parent);
if(pParent)
setParent(pParent);
@ -29,6 +32,7 @@ void DiagramEditorPreviewDlg::initial()
{
_pMainLayout = new QVBoxLayout(this);
_pView = new EditView(this);
_pView->scale(0.5, 0.5);
_pMainLayout->addWidget(_pView);
_pScene = new EditPreviewScene(this);
_pScene->setSceneRect(_pParent->getScene()->sceneRect()); //使用父窗口scene大小
@ -39,9 +43,24 @@ void DiagramEditorPreviewDlg::initial()
void DiagramEditorPreviewDlg::showDlg()
{
if(_pParent){
_pScene->clear();
_pParent->getModel()->setCurPreviewScene(_pScene);
}
show();
show();
// 设置大小为屏幕的1/3
QScreen *screen = QGuiApplication::primaryScreen();
QRect rec = screen->availableGeometry();
int w = rec.width() / 3;
int h = rec.height() / 3;
// 确保最小尺寸
w = qMax(w, 400);
h = qMax(h, 300);
resize(w, h);
QRect mainRect = screen->availableGeometry();
int x = mainRect.right() - width();
int y = mainRect.bottom() - height();
move(x, y);
}

View File

@ -466,6 +466,9 @@ void DiagramEditorTransDetailAddDlg::onOkClicked()
}
}
}
if(_pParent){
_pParent->showPreview();
}
hide();
}

View File

@ -10,14 +10,14 @@
#include "topologyManager.h"
#include "diagramEditor/diagramEditorTransPreviewDlg.h"
DiagramEditorTransDetailSettingDlg::DiagramEditorTransDetailSettingDlg(QWidget *parent)
DiagramEditorTransDetailSettingDlg::DiagramEditorTransDetailSettingDlg(QWidget *parent,DiagramEditorModel* pModel)
: QDialog(parent)
, ui(new Ui::diagramEditorTransDetailSettingDlg)
,_pAddDlg(nullptr)
,_curOperateObj(nullptr)
,_compoModel(nullptr)
,_pPreviewDlg(nullptr)
,_pModel(nullptr)
,_pModel(pModel)
,_curOperateRouteView(nullptr)
{
ui->setupUi(this);
@ -53,11 +53,12 @@ void DiagramEditorTransDetailSettingDlg::initial()
connect(ui->btn_add,&QPushButton::clicked,this,&DiagramEditorTransDetailSettingDlg::onAddClicked);
connect(ui->btn_ok,&QPushButton::clicked,this,&DiagramEditorTransDetailSettingDlg::onOkClicked);
connect(ui->btn_cancel,&QPushButton::clicked,this,&DiagramEditorTransDetailSettingDlg::onCancelClicked);
connect(ui->btn_previewEquips,&QPushButton::clicked,this,&DiagramEditorTransDetailSettingDlg::onPreviewNeutralClicked);
connect(ui->btn_previewTrans,&QPushButton::clicked,this,&DiagramEditorTransDetailSettingDlg::onPreviewTransClicked);
connect(ui->tableView_hv, &QTableView::customContextMenuRequested, this, &DiagramEditorTransDetailSettingDlg::onRouteRbtnClicked);
connect(ui->tableView_mv, &QTableView::customContextMenuRequested, this, &DiagramEditorTransDetailSettingDlg::onRouteRbtnClicked);
connect(ui->tableView_lv, &QTableView::customContextMenuRequested, this, &DiagramEditorTransDetailSettingDlg::onRouteRbtnClicked);
connect(ui->cb_previewType,&QComboBox::currentIndexChanged,this,[&](int index){
showPreview();
});
ui->tableView_hv->setContextMenuPolicy(Qt::CustomContextMenu);
ui->tableView_hv->setSelectionMode(QAbstractItemView::SingleSelection);
@ -76,6 +77,19 @@ void DiagramEditorTransDetailSettingDlg::initial()
ui->tableView_lv->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView_lv->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView_lv->verticalHeader()->setVisible(false);
if(_pPreviewDlg == nullptr){
_pPreviewDlg = new DiagramEditorTransPreviewDlg(this);
_pPreviewDlg->setParent(this);
if(_pModel){
_pModel->setCurTransComponentModel(_compoModel);
_pModel->setCurTransRouteModels(_routeModels);
}
_pPreviewDlg->setSceneRect(ui->tableView_hv->rect());
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(_pPreviewDlg);
ui->groupBox_preview->setLayout(layout);
}
}
void DiagramEditorTransDetailSettingDlg::refreshModel()
@ -318,6 +332,10 @@ void DiagramEditorTransDetailSettingDlg::onOkClicked()
}
hide();
_pModel->clearCurPreview(); //关闭时清除预览Item
_pModel->generatePreview();
_pModel->calculateBlockPos();
_pModel->setItemInBlockPos();
_pModel->refreshConnection();
//todo:清除mainPanel中的对应item(如果存在)
}
@ -425,37 +443,22 @@ void DiagramEditorTransDetailSettingDlg::onRouteEditClicked()
_pAddDlg->showDlg(routeInfo);
}
void DiagramEditorTransDetailSettingDlg::onPreviewNeutralClicked()
void DiagramEditorTransDetailSettingDlg::showPreview()
{
if(_pPreviewDlg == nullptr){
_pPreviewDlg = new DiagramEditorTransPreviewDlg(this);
_pPreviewDlg->setParent(this);
_pModel->setCurTransComponentModel(_compoModel);
_pModel->setCurTransRouteModels(_routeModels);
}
if(!_pPreviewDlg->isVisible()){
int n = ui->cb_previewType->currentIndex();
if(n == 0){ //中性点预览
int n = ui->tabWidget->currentIndex();
_pPreviewDlg->showDlg(n);
_pModel->clearCurPreview();
_pModel->generateTempTrans(n,_curOperateObj);
if(_pModel){
_pModel->clearCurPreview();
_pModel->generateTempTrans(n,_curOperateObj);
}
}
else
_pPreviewDlg->hide();
}
void DiagramEditorTransDetailSettingDlg::onPreviewTransClicked()
{
if(_pPreviewDlg == nullptr){
_pPreviewDlg = new DiagramEditorTransPreviewDlg(this);
_pPreviewDlg->setParent(this);
_pModel->setCurTransComponentModel(_compoModel);
_pModel->setCurTransRouteModels(_routeModels);
}
if(!_pPreviewDlg->isVisible()){
else{ //变压器预览
_pPreviewDlg->showDlg(3);
_pModel->clearCurPreview();
_pModel->generateTempTrans(3,_curOperateObj);
if(_pModel){
_pModel->clearCurPreview();
_pModel->generateTempTrans(3,_curOperateObj);
}
}
else
_pPreviewDlg->hide();
}

View File

@ -37,7 +37,7 @@ void DiagramEditorTransPreviewDlg::showDlg(int nType)
if(_pParent){
_pParent->getModel()->setCurPreviewScene(_pScene);
}
show();
//show();
updateModelData(nType);
}
@ -60,3 +60,9 @@ void DiagramEditorTransPreviewDlg::updateModelData(int nType)
_pParent->getModel()->updateTarget(_pParent->getTransInfo().mapNeutral[2].mapRoute,_pParent->getTransInfo().mapComponent,14,1); //1右2下
}
}
void DiagramEditorTransPreviewDlg::setSceneRect(const QRect rec)
{
if(_pScene)
_pScene->setSceneRect(-rec.width()*0.5,-rec.height()*0.5,rec.width(),rec.height());
}

View File

@ -61,6 +61,8 @@ EditPanel::~EditPanel()
void EditPanel::initByWizardInfo()
{
QList<RelationItem> lstBay;
QList<RelationItem> lstItem;
//if(!_lstData.empty() || !_pModel->getPreviewItem().empty()){
_pModel->clearItems();
m_pEditScene->clear();
@ -112,6 +114,31 @@ void EditPanel::initByWizardInfo()
pItem = pBus;
layH->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
layH->setPreferredHeight(10); // 固定高度
RelationItem info;
info.item.nEquipType = 1;
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = pBlock->getName();
info.item.uid = pBlock->getId(); //间隔id与对象id此处相同(表示此间隔对应一个设备)
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
QString sVoltageLevel;
bayTag = pBlock->getName();
bayUuid = pBlock->getId().toString();
sVoltageLevel = QString::number(pBlock->getVoltage());
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
info.parent.sVoltageLevel = sVoltageLevel;
}
lstItem.append(info);
}
else if(nType == 2){ //间隔
auto pBay = new EditBayItem();
@ -126,6 +153,14 @@ void EditPanel::initByWizardInfo()
}*/
if(pItem){
RelationItem bayInfo; //间隔层级
bayInfo.item.nEquipType = 0; // 间隔的设备类型为0
bayInfo.item.nCategory = 1; // 类别为1表示间隔
bayInfo.item.sName = pBlock->getName();
bayInfo.item.uid = pBlock->getId();
bayInfo.item.sVoltageLevel = QString::number(pBlock->getVoltage());
lstBay.append(bayInfo);
connect(pItem,&EditBaseItem::itemDbClicked,this,&EditPanel::onItemDbClicked);
pItem->setName(pBlock->getName());
pItem->setBlockData(pBlock);
@ -209,9 +244,42 @@ void EditPanel::initByWizardInfo()
pTrans->setType(EditorItemType::trans);
pTrans->setBoundingRect(QRectF(0,0,g_dEditorItem_Width,g_dEditorItem_Width));
pItem = pTrans;
RelationItem info;
info.item.nEquipType = 16;
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = pBlock->getName();
info.item.uid = pBlock->getId(); //间隔id与对象id此处相同(表示此间隔对应一个设备)
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
QString sVoltageLevel;
bayTag = pBlock->getName();
bayUuid = pBlock->getId().toString();
sVoltageLevel = QString::number(pBlock->getVoltage());
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
info.parent.sVoltageLevel = sVoltageLevel;
}
lstItem.append(info);
}
if(pItem){
RelationItem bayInfo; //间隔层级
bayInfo.item.nEquipType = 0; // 间隔的设备类型为0
bayInfo.item.nCategory = 1; // 类别为1表示间隔
bayInfo.item.sName = pBlock->getName();
bayInfo.item.uid = pBlock->getId();
bayInfo.item.sVoltageLevel = QString::number(pBlock->getVoltage());
lstBay.append(bayInfo);
connect(pItem,&EditBaseItem::itemDbClicked,this,&EditPanel::onItemDbClicked);
pItem->setName(pBlock->getName());
pItem->setBlockData(pBlock);
@ -231,6 +299,8 @@ void EditPanel::initByWizardInfo()
}
}
_widgetLayout->addStretch();
emit _pModel->updateTopologyItems(lstBay,true);
emit _pModel->updateTopologyItems(lstItem,false);
QTimer::singleShot(300, [&]() { // 1000 毫秒 = 1 秒
qDebug() << "一次性定时器触发!";
initBlockConnection();
@ -469,23 +539,23 @@ void EditPanel::onItemDbClicked(QPointer<DiagramEditorBaseBlock> pBlock)
{
if(pBlock->getType() == 2){ //间隔
if(_bayDetailSetting == nullptr){
_bayDetailSetting = new DiagramEditorBayDetailSettingDlg(this);
_bayDetailSetting->setModelDelegate(_pModel);
_bayDetailSetting = new DiagramEditorBayDetailSettingDlg(this,_pModel);
_bayDetailSetting->setWizard(_pEditorWizard);
}
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(pBlock.data());
if(pBay)
_bayDetailSetting->showDlg(pBay);
_bayDetailSetting->showPreview();
}
else if(pBlock->getType() == 3){ //变压器
if(_transDetailSetting == nullptr){
_transDetailSetting = new DiagramEditorTransDetailSettingDlg(this);
_transDetailSetting->setModelDelegate(_pModel);
_transDetailSetting = new DiagramEditorTransDetailSettingDlg(this,_pModel);
_transDetailSetting->setWizard(_pEditorWizard);
}
auto pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(pBlock.data());
if(pTrans)
_transDetailSetting->showDlg(pTrans);
_transDetailSetting->showPreview();
}
}

View File

@ -222,19 +222,19 @@ void DrawingPanel::loadNodes(QJsonObject obj)
}
if(_pModel){
QList<monitorRelationItem> lstFirst;
QList<RelationItem> lstFirst;
for(auto& pBaseItem:_pModel->getProjectItems()) //首次循环添加母线及独立设备(变压器等),更新列表显示使用
{
BaseProperty* pBase = dynamic_cast<BaseProperty*>(pBaseItem->getProperty());
if(pBase->type() == 1){ //母线添加子间隔
monitorRelationItem info;
RelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0;
info.item.sName = pBase->name();
info.item.uid = pBase->uuid();
for(auto& subPair:pBase->getSubList()){
monitorRelationSturctItem subStruct;
RelationSturctItem subStruct;
BayProperty* pTargetBay = nullptr;
for(auto& pOtherItem:_pModel->getProjectBayItems())
@ -259,14 +259,14 @@ void DrawingPanel::loadNodes(QJsonObject obj)
lstFirst.append(info);
}
else if(pBase->type() == 15 || pBase->type() == 16){
monitorRelationItem info;
RelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0;
info.item.sName = pBase->name();
info.item.uid = pBase->uuid();
for(auto& subPair:pBase->getSubList()){
monitorRelationSturctItem subStruct;
RelationSturctItem subStruct;
ModelProperty* pPro = nullptr;
for(auto& item:_pModel->getProjectItems()){
@ -290,12 +290,12 @@ void DrawingPanel::loadNodes(QJsonObject obj)
}
emit _pModel->updateCurrentItems(lstFirst,true);
QList<monitorRelationItem> lstSecond;
QList<RelationItem> lstSecond;
for(auto& pBaseItem:_pModel->getProjectItems()) //二次循环添加间隔内设备(更新列表显示使用)
{
BaseProperty* pBase = dynamic_cast<BaseProperty*>(pBaseItem->getProperty());
if(pBase->type() != 1 && pBase->type() != 15 && pBase->type() != 16){ //设备添加
monitorRelationItem info;
RelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0;
info.item.sName = pBase->name();
@ -306,7 +306,9 @@ void DrawingPanel::loadNodes(QJsonObject obj)
{
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay){
if(pBay->tag() == pBase->getBay()){ //将bay添加到parent
QString bayTag = pBay->tag();
QString parentTag = pBase->getBay();
if(bayTag == parentTag){ //将bay添加到parent
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = pBay->tag();

View File

@ -39,6 +39,13 @@ DiagramEditorModel::~DiagramEditorModel()
}
void DiagramEditorModel::clearItems()
{
_previewItem.clear();
if(_pCurPreviewScene)
_pCurPreviewScene->clear();
}
bool DiagramEditorModel::addPreviewItem(QUuid uuid,GraphicsBaseModelItem* pItem,int mode)
{
if(mode == 0){
@ -478,104 +485,193 @@ void DiagramEditorModel::linkTransItem(GraphicsBaseModelItem* pTrans,QStandardIt
}
}
void DiagramEditorModel::generatePreview()
void DiagramEditorModel::generatePreview(bool bVisible)
{
if(_pPanel){
QList<RelationItem> lstBay;
QList<RelationItem> lstItem;
clearItems();
_pPanel->showPreview();
if(bVisible)
_pPanel->showPreview();
QList<EditBaseItem*> lst = _pPanel->getBlockItems();
QMap<QString,QList<DiagramEditorComponentInfo>> baysCompo;
QMap<QString,QMap<int,QList<DiagramEditorComponentInfo>>> transCompo;
for(auto item:lst){
if(item->getType() == EditorItemType::bus){ //首次循环生成母线
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorBusBlock* pBus = dynamic_cast<DiagramEditorBusBlock*>(p.data());
if(pBus){
QUuid uid = p->getId();
QString name = p->getName();
auto pContainer = _pWizard->getContainerByBlock_all(name); //获取block所在的container
auto p = item->getBlockData(); //获取blockitem对应的data
if(p){
RelationItem bayInfo; //间隔层级
bayInfo.item.nEquipType = 0; // 间隔的设备类型为0
bayInfo.item.nCategory = 1; // 类别为1表示间隔
bayInfo.item.sName = p->getName();
bayInfo.item.uid = p->getId();
bayInfo.item.sVoltageLevel = QString::number(p->getVoltage());
lstBay.append(bayInfo);
if(item->getType() == EditorItemType::bus){ //首次循环生成母线
DiagramEditorBusBlock* pBus = dynamic_cast<DiagramEditorBusBlock*>(p.data());
if(pBus){
QUuid uid = p->getId();
QString name = p->getName();
auto pContainer = _pWizard->getContainerByBlock_all(name); //获取block所在的container
auto mapBlocks = pContainer->getBlockMap();
int nMaxLen = 0;
for(auto &lst:mapBlocks){ //根据容器中block的最大长度计算出母线最小length
int nLen = 0;
for(auto block:lst){
if(block->getType() == 1) //容器中block是母线不计算
continue;
nLen = 100+block->getRecSize().width();
auto mapBlocks = pContainer->getBlockMap();
int nMaxLen = 0;
for(auto &lst:mapBlocks){ //根据容器中block的最大长度计算出母线最小length
int nLen = 0;
for(auto block:lst){
if(block->getType() == 1) //容器中block是母线不计算
continue;
nLen = 100+block->getRecSize().width();
}
if(nMaxLen < nLen)
nMaxLen = nLen;
}
if(nMaxLen < nLen)
nMaxLen = nLen;
QRectF rec = item->boundingRect();
QPointF pos = item->scenePos();
if(_previewItem.contains(uid))
continue;
auto pItem = generateComponent(uid,name,0,1,pos,0,1,pBus);
pBus->addSubList(qMakePair(0,uid));
if(nMaxLen > rec.width())
rec.setWidth(nMaxLen);
pItem->setBoundingRect(rec);
pBus->setRecSize(rec);
RelationItem info;
info.item.nEquipType = 1;
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = p->getName();
info.item.uid = p->getId(); //间隔id与对象id此处相同(表示此间隔对应一个设备)
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
QString sVoltageLevel;
bayTag = p->getName();
bayUuid = p->getId().toString();
sVoltageLevel = QString::number(p->getVoltage());
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
info.parent.sVoltageLevel = sVoltageLevel;
}
lstItem.append(info);
}
QRectF rec = item->boundingRect();
QPointF pos = item->scenePos();
if(_previewItem.contains(uid))
continue;
auto pItem = generateComponent(uid,name,0,1,pos,0,1,pBus);
if(nMaxLen > rec.width())
rec.setWidth(nMaxLen);
pItem->setBoundingRect(rec);
pBus->setRecSize(rec);
}
}
else if(item->getType() == EditorItemType::bay){ //第二次生成间隔、变压器
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorBayBlock* pBay = dynamic_cast<DiagramEditorBayBlock*>(p.data());
if(pBay){
QString sBay = pBay->getName();
auto mapRoute = pBay->getBayInfo().mapRoute;
auto mapCompo = pBay->getBayInfo().mapComponent;
else if(item->getType() == EditorItemType::bay){ //第二次生成间隔、变压器
DiagramEditorBayBlock* pBay = dynamic_cast<DiagramEditorBayBlock*>(p.data());
if(pBay){
QString sBay = pBay->getName();
auto mapRoute = pBay->getBayInfo().mapRoute;
auto mapCompo = pBay->getBayInfo().mapComponent;
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
QList<DiagramEditorComponentInfo> lstCompo = generateItemByInfo(mapRoute,mapCompo,centerScene,pBay); //返回与外部连接的compo
if(!baysCompo.contains(sBay))
baysCompo.insert(sBay,lstCompo);
}
}
else if(item->getType() == EditorItemType::trans){
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorTransformerBlock* pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(p.data());
if(pTrans){
//首先绘制本体
auto pType = pTrans->getTransType();
QString sTrans = pTrans->getName();
QUuid uid = pTrans->getId();
QString name = pTrans->getName();
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
QList<DiagramEditorComponentInfo> lstCompo = generateItemByInfo(mapRoute,mapCompo,centerScene,pBay); //返回与外部连接的compo
if(!baysCompo.contains(sBay))
baysCompo.insert(sBay,lstCompo);
for(auto& compo:lstCompo){
RelationItem info;
info.item.nEquipType = compo.nType;
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = compo.sName;
info.item.uid = compo.uid; //间隔id与对象id此处相同(表示此间隔对应一个设备)
QPointF pos = item->scenePos();
int nType = 0;
if(pType == TransformerType::twoWinding)
nType = 15;
else
nType = 16;
auto pItem = generateComponent(uid,name,0,nType,pos,0,1,pTrans);
auto pro = pItem->getProperty();
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
QString sVoltageLevel;
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
auto transInfo = pTrans->getTranInfo();
bayTag = p->getName();
bayUuid = p->getId().toString();
sVoltageLevel = QString::number(p->getVoltage());
QMap<int,QList<DiagramEditorComponentInfo>> neutralInfo;
for(auto &neutral:transInfo.mapNeutral){
QPointF pDelta = neutral.delPoint;
int nT = neutral.nType;
QList<DiagramEditorComponentInfo> lstCompo = generateItemByInfo(neutral.mapRoute,transInfo.mapComponent,centerScene+pDelta,pTrans);
if(!neutralInfo.contains(nT))
neutralInfo.insert(nT,lstCompo);
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
info.parent.sVoltageLevel = sVoltageLevel;
}
lstItem.append(info);
}
}
}
else if(item->getType() == EditorItemType::trans){
DiagramEditorTransformerBlock* pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(p.data());
if(pTrans){
//首先绘制本体
auto pType = pTrans->getTransType();
QString sTrans = pTrans->getName();
QUuid uid = pTrans->getId();
QString name = pTrans->getName();
if(!transCompo.contains(sTrans)) //添加需连接的中性点
transCompo.insert(sTrans,neutralInfo);
QPointF pos = item->scenePos();
int nType = 0;
if(pType == TransformerType::twoWinding)
nType = 15;
else
nType = 16;
auto pItem = generateComponent(uid,name,0,nType,pos,0,1,pTrans);
auto pro = pItem->getProperty();
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
auto transInfo = pTrans->getTranInfo();
QMap<int,QList<DiagramEditorComponentInfo>> neutralInfo;
for(auto &neutral:transInfo.mapNeutral){
QPointF pDelta = neutral.delPoint;
int nT = neutral.nType;
QList<DiagramEditorComponentInfo> lstCompo = generateItemByInfo(neutral.mapRoute,transInfo.mapComponent,centerScene+pDelta,pTrans);
if(!neutralInfo.contains(nT))
neutralInfo.insert(nT,lstCompo);
for(auto& compo:lstCompo){
RelationItem info;
info.item.nEquipType = compo.nType;
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = p->getName();
info.item.uid = p->getId(); //间隔id与对象id此处相同(表示此间隔对应一个设备)
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
QString sVoltageLevel;
bayTag = p->getName();
bayUuid = p->getId().toString();
sVoltageLevel = QString::number(p->getVoltage());
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
info.parent.sVoltageLevel = sVoltageLevel;
}
lstItem.append(info);
}
}
if(!transCompo.contains(sTrans)) //添加需连接的中性点
transCompo.insert(sTrans,neutralInfo);
}
}
}
}
@ -678,6 +774,8 @@ void DiagramEditorModel::generatePreview()
}
}
}
emit updateTopologyItems(lstBay,true);
emit updateTopologyItems(lstItem,false);
}
}

View File

@ -1007,6 +1007,7 @@ void FixedPortsModel::saveNode(int nPageId)
for(auto& info:lstTemp){
if(info.component_uuid != QUuid("11111111-1111-1111-1111-111111111111")) //只判断设备外量测
continue;
info.bay_tag = removeSuffix(info.bay_tag);
lstExtra.append(info);
}
@ -1107,7 +1108,7 @@ void FixedPortsModel::saveNode(int nPageId)
extraPro.currentLevel = QString::number(pBay->getVoltage())+"kv";
extraPro.page_tag = _widget->pageName(); //暂时相同
extraPro.bay_name = pBay->name();
extraPro.bay_tag = pBay->tag();
extraPro.bay_tag = tempTag;
extraPro.component_uuid = QUuid("11111111-1111-1111-1111-111111111111");
for(auto& groupInfo:groupMap){
@ -1325,6 +1326,7 @@ void FixedPortsModel::saveNode(int nPageId)
for(auto& info:lstTemp){
if(info.group_tag != "bay") //只对量测判断
continue;
info.bay_tag = removeSuffix(info.bay_tag);
lstExtra.append(info);
}
@ -2118,102 +2120,85 @@ void FixedPortsModel::generateProjectModel(const QString& sPageName,QList<Graphi
lstBase.append(p);
}
QList<monitorRelationItem> lstFirst;
for(auto& pBaseItem:lstItem) //首次循环添加母线及独立设备(变压器等),更新列表显示使用
{
BaseModelProperty* pBase = dynamic_cast<BaseModelProperty*>(pBaseItem->getProperty());
if(pBase->type() == 1){ //母线添加子间隔
monitorRelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0;
info.item.sName = pBase->name();
info.item.uid = pBase->uuid();
for(auto& subPair:pBase->getSubList()){
monitorRelationSturctItem subStruct;
BayProperty* pTargetBay = nullptr;
for(auto& pOtherItem:lstOther)
{
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay){
if(pBay->uuid() == subPair.second){ //从所有间隔中找到sublist中的间隔
pTargetBay = pBay;
break;
}
}
}
if(pTargetBay){
subStruct.nEquipType = 0;
subStruct.nCategory = 1;
subStruct.sName = pTargetBay->tag();
subStruct.uid = pTargetBay->uuid();
info.subList.append(subStruct);
}
}
lstFirst.append(info);
}
else if(pBase->type() == 15 || pBase->type() == 16){
monitorRelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0;
info.item.sName = pBase->name();
info.item.uid = pBase->uuid();
for(auto& subPair:pBase->getSubList()){
monitorRelationSturctItem subStruct;
auto pPro = getItemByUid(lstBase,subPair.second);
if(pPro){
subStruct.nEquipType = pPro->type();
subStruct.nCategory = 0;
subStruct.sName = pPro->name();
subStruct.uid = pPro->uuid();
info.subList.append(subStruct);
}
}
lstFirst.append(info);
}
}
emit updateCurrentItems(lstFirst,true);
QList<monitorRelationItem> lstSecond;
for(auto& pBaseItem:lstItem) //二次循环添加间隔内设备(更新列表显示使用)
{
BaseModelProperty* pBase = dynamic_cast<BaseModelProperty*>(pBaseItem->getProperty());
if(pBase->type() != 1 && pBase->type() != 15 && pBase->type() != 16){ //设备添加
monitorRelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0;
info.item.sName = pBase->name();
info.item.uid = pBase->uuid();
BayProperty* pTargetBay = nullptr;
for(auto& pOtherItem:lstOther)
{
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay){
if(pBay->tag() == pBase->getBay()){ //将bay添加到parent
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = pBay->tag();
info.parent.uid = pBay->uuid();
break;
}
}
}
lstSecond.append(info);
}
}
emit updateCurrentItems(lstSecond,false);
QList<RelationItem> lstFirst;
for(auto& pOtherItem:lstOther)
{
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay){
BayProperty* pData = pProPanel->getModelController()->generateBayData(pBay,lstProData);
// 创建间隔项
RelationItem bayInfo;
bayInfo.item.nEquipType = 0; // 间隔的设备类型为0
bayInfo.item.nCategory = 1; // 类别为1表示间隔
bayInfo.item.sName = pBay->tag();
bayInfo.item.uid = pBay->uuid();
lstFirst.append(bayInfo);
}
}
emit updateCurrentItems(lstFirst, true);
// 第二阶段:处理所有设备
QList<RelationItem> lstSecond;
// 建立间隔UUID到间隔标签的映射提高查找效率
QHash<QString, QString> bayUuidToTag;
for(auto& pOtherItem:lstOther)
{
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay){
bayUuidToTag[pBay->uuid().toString()] = pBay->tag();
}
}
for(auto& pBaseItem:lstItem)
{
BaseModelProperty* pBase = dynamic_cast<BaseModelProperty*>(pBaseItem->getProperty());
RelationItem info;
info.item.nEquipType = pBase->type();
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = pBase->name();
info.item.uid = pBase->uuid();
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
// 通过间隔标签直接查找
bayTag = pBase->getBay();
// 如果需要间隔UUID可以反向查找
if(!bayTag.isEmpty()){
for(auto& pOtherItem:lstOther){
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay && pBay->tag() == bayTag){
bayUuid = pBay->uuid().toString();
break;
}
}
}
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
}
lstSecond.append(info);
}
emit updateCurrentItems(lstSecond, false);
// 第三阶段:生成间隔数据(保持不变)
for(auto& pOtherItem:lstOther)
{
BayProperty* pBay = dynamic_cast<BayProperty*>(pOtherItem->getProperty());
if(pBay){
BayProperty* pData = pProPanel->getModelController()->generateBayData(pBay, lstProData);
if(pData)
{
pData->setSubList(pBay->getSubList());
@ -2235,10 +2220,45 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
}
//pPanel->getModelController()->addTestData();
QList<RelationItem> lstItem;
for(auto pItem:mapItem){
auto cloneItem = pItem->clone();
BaseModelProperty* pPro = BasePropertyManager::instance().findBaseEntityData(cloneItem->itemId());
if(pPro){
RelationItem info;
info.item.nEquipType = pPro->type();
info.item.nCategory = 0; // 类别为0表示设备
info.item.sName = pPro->name();
info.item.uid = pPro->uuid();
// 查找设备所属的间隔
QString bayTag;
QString bayUuid;
QString sVoltageLevel;
// 通过间隔标签直接查找
bayTag = pPro->getBay();
// 如果需要间隔UUID可以反向查找
if(!bayTag.isEmpty()){
for(auto& pItem:mapBlock){
auto pBlock = pItem->getBlockData();
if(pBlock && pBlock->getName() == bayTag){
bayUuid = pBlock->getId().toString();
sVoltageLevel = QString::number(pBlock->getVoltage());
break;
}
}
}
if(!bayTag.isEmpty()){
// 设置父间隔信息
info.parent.nEquipType = 0;
info.parent.nCategory = 1;
info.parent.sName = bayTag;
info.parent.uid = QUuid(bayUuid);
info.parent.sVoltageLevel = sVoltageLevel;
}
lstItem.append(info);
if(pPro->type() == 1){ //母线
for(auto item:mapBlock){
auto p = item->getBlockData(); //获取blockitem对应的data
@ -2249,7 +2269,7 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
if(sBus == pPro->name()){
double dVol = pBus->getVoltage();
pPro->setVoltageLevel(dVol); //设置本体电压层级
pPro->setSubList(pBus->getSubList()); //将子列表转移到item
//pPro->setSubList(pBus->getSubList()); //将子列表转移到item
}
}
}
@ -2265,7 +2285,7 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
if(sTrans == pPro->name()){
double dVol = pTrans->getVoltage();
pPro->setVoltageLevel(dVol); //设置本体电压
pPro->setSubList(pTrans->getSubList()); //将子列表转移到item
//pPro->setSubList(pTrans->getSubList()); //将子列表转移到item
}
}
}
@ -2325,8 +2345,19 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
//_widget->getView()->centerOn(center);
//**************间隔*************
QList<RelationItem> lstBay;
for(auto item:mapBlock){
auto p = item->getBlockData(); //获取blockitem对应的data
//间隔信息
RelationItem bayInfo;
bayInfo.item.nEquipType = 0; // 间隔的设备类型为0
bayInfo.item.nCategory = 1; // 类别为1表示间隔
bayInfo.item.sName = p->getName();
bayInfo.item.uid = p->getId();
bayInfo.item.sVoltageLevel = QString::number(p->getVoltage());
lstBay.append(bayInfo);
if(p->getType() == 1){ //母线
DiagramEditorBusBlock* pBus = dynamic_cast<DiagramEditorBusBlock*>(p.data());
if(pBus){
@ -2352,7 +2383,8 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
pBayData->setName(sBus);
pBayData->setTag(sBus);
pBayData->setType("母线间隔");
//pBayData->setSubList(pBus->getSubList());
pBayData->setVoltage(pBus->getVoltage());
pBayData->setSubList(pBus->getSubList());
pBayData->getLstComponent().append(busId);
addBayItem(bayId,pNew,ModelFunctionType::BaseModel);
@ -2427,6 +2459,7 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
pBayData->setName(sBay);
pBayData->setTag(sBay);
pBayData->setType(sType);
pBayData->setVoltage(pBay->getVoltage());
pBayData->setLstFrom(pBay->getBayInfo().lstFrom);
pBayData->setLstTo(pBay->getBayInfo().lstTo);
pBayData->setSubList(pBay->getSubList());
@ -2497,6 +2530,7 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
pBayData->setName(sTrans);
pBayData->setTag(sTrans);
pBayData->setType(sType);
pBayData->setVoltage(pTrans->getVoltage());
pBayData->setSubList(pTrans->getSubList());
for(auto &info:lstInfo){
@ -2508,20 +2542,23 @@ void FixedPortsModel::onWizardFinished(QMap<QUuid,GraphicsBaseModelItem*> mapIte
}
}
}
emit updateTopologyItems(lstBay,true);
emit updateTopologyItems(lstItem,false);
}
void FixedPortsModel::addProjectItemByBaseData(DrawingPanel* pPanel,GraphicsBaseModelItem* pItem,BaseProperty* pPro,QString sGrid,QString sZone,QString sStation)
{
BaseModelProperty* pBase = dynamic_cast<BaseModelProperty*>(pItem->getProperty());
if(pBase){
QString sBay = pBase->getBay();
if(_baseItem.contains(pBase->uuid())){
GraphicsProjectModelItem* pProItem = nullptr;
GraphicsBaseModelItem* pBaseItem = _baseItem.value(pBase->uuid());
pPro->setSourceItemId(pBaseItem->itemId().toString()); //设置被哪个对象生成
pPro->setMetaModelName(pBase->metaModelName()); //传递基模名
pPro->setPath(pBase->getBay());
pPro->setPath(sBay);
pPro->setSubList(pBase->getSubList()); //传递sublist
pPro->setBay(pBase->getBay());
pPro->setBay(sBay);
pPro->setVoltageLevel(pBase->getVoltageLevel());
QString sMeta = pBase->metaModelName();
@ -3306,7 +3343,7 @@ QList<QUuid> FixedPortsModel::turnJsonArrToList(QJsonObject object,QString sInne
return lst;
}
void FixedPortsModel::generateMonitor(QString sPage,QList<monitorRelationItem> lst)
void FixedPortsModel::generateMonitor(QString sPage,QList<RelationItem> lst)
{
MonitorPanel* pPanel = nullptr;
if(_cavas){
@ -3323,7 +3360,7 @@ void FixedPortsModel::generateMonitor(QString sPage,QList<monitorRelationItem> l
_widget->getGeneratePanelLst().append(sPage); //记录生成的运行页
pPanel->setParentPage(_pageName); //生成页记录被哪个组态生成
QList<monitorRelationItem> lstFirst;
QList<RelationItem> lstFirst;
for(auto& itemInfo:lst)
{
if(itemInfo.item.nCategory == 0){ //设备
@ -3358,7 +3395,7 @@ void FixedPortsModel::generateMonitor(QString sPage,QList<monitorRelationItem> l
}
}
QList<monitorRelationItem> lstSecond;
QList<RelationItem> lstSecond;
for(auto& itemInfo:lst) //第二次循环处理间隔
{
if(itemInfo.item.nCategory == 1){ //间隔

View File

@ -41,54 +41,215 @@ void ElectricConnectLineItem::initial()
void ElectricConnectLineItem::setStartPoint(const QPointF& p)
{
int n = m_lstPoints.size();
if(n)
{
if(n >2)
{
if(m_lstPoints[0].x() == m_lstPoints[1].x()) //相邻点在垂直方向,水平移动,否则垂直移动
{
m_lstPoints[1].setX(p.x());
}
else
{
m_lstPoints[1].setY(p.y());
}
}
if (m_lstPoints.size() >= 2) {
// 保存终点
QPointF endPoint = m_lstPoints.last();
// 清空并设置新起点
m_lstPoints.clear();
m_lstPoints.append(p);
m_lstPoints.append(endPoint);
// 重新计算路径
calculatePath();
} else if (m_lstPoints.size() == 1) {
m_lstPoints[0] = p;
} else {
m_lstPoints.append(p);
}
update();
}
void ElectricConnectLineItem::setEndPoint(const QPointF& p)
{
int n = m_lstPoints.size();
if(n)
{
if(n >2)
{
if(m_lstPoints[n-1].x() == m_lstPoints[n-2].x()) //相邻点在垂直方向,水平移动,否则垂直移动
{
m_lstPoints[n-2].setX(p.x());
}
else
{
m_lstPoints[n-2].setY(p.y());
}
}
m_lstPoints[n-1] = p;
if (m_lstPoints.size() >= 2) {
// 保存起点
QPointF startPoint = m_lstPoints.first();
// 清空并设置新终点
m_lstPoints.clear();
m_lstPoints.append(startPoint);
m_lstPoints.append(p);
// 重新计算路径
calculatePath();
} else if (m_lstPoints.size() == 1) {
m_lstPoints.append(p);
} else {
m_lstPoints.append(p);
}
update();
}
// 开始拖拽
void ElectricConnectLineItem::startDrag(const QPointF& scenePos)
{
qDebug() << "\n=== START DRAG ===";
// 重置状态
m_dragData.isActive = false;
m_dragData.segmentIndex = -1;
QPointF itemPos = mapFromScene(scenePos);
qDebug() << "Item pos:" << itemPos;
// 从路径提取点
QList<QPointF> points = extractPointsFromPath();
qDebug() << "Extracted" << points.size() << "points from path";
// 查找线段
int segmentIndex = findSegmentAt(points, itemPos);
if (segmentIndex >= 0) {
m_dragData.isActive = true;
m_dragData.segmentIndex = segmentIndex;
m_dragData.startScenePos = scenePos;
m_dragData.originalPath = m_points; // 保存原始路径
// 判断线段方向
if (segmentIndex < points.size() - 1) {
QPointF p1 = points[segmentIndex];
QPointF p2 = points[segmentIndex + 1];
m_dragData.isVertical = qFuzzyCompare(p1.x(), p2.x());
}
qDebug() << "✓ Dragging segment" << segmentIndex;
}
}
// 更新拖拽
void ElectricConnectLineItem::updateDrag(const QPointF& scenePos)
{
if (!m_dragData.isActive) {
return;
}
int idx = m_dragData.segmentIndex;
// 从原始路径提取点
QList<QPointF> points = extractPointsFromPath(m_dragData.originalPath);
// 安全检查
if (idx < 0 || idx >= points.size() - 1) {
qWarning() << "Invalid segment index:" << idx;
m_dragData.isActive = false;
return;
}
// 计算移动距离
QPointF startItemPos = mapFromScene(m_dragData.startScenePos);
QPointF currentItemPos = mapFromScene(scenePos);
QPointF delta = currentItemPos - startItemPos;
// 获取当前线段
QPointF& p1 = points[idx];
QPointF& p2 = points[idx + 1];
// 限制移动方向
if (m_dragData.isVertical) {
// 垂直线段:只能水平移动
delta.setY(0);
// 移动线段
p1.rx() += delta.x();
p2.rx() += delta.x();
} else {
// 水平线段:只能垂直移动
delta.setX(0);
p1.ry() += delta.y();
p2.ry() += delta.y();
}
// 修复连接
fixConnections(points, idx, m_dragData.isVertical);
// 更新拖拽起点
m_dragData.startScenePos = scenePos;
// 应用修改后的点
applyPointsToPath(points);
// 重新计算路径(调用原有的 calculatePath
calculatePath();
update();
}
// 结束拖拽
void ElectricConnectLineItem::endDrag()
{
qDebug() << "\n" << QString(50, '=');
qDebug() << "END DRAG";
qDebug() << QString(50, '=');
if (!m_dragData.isActive) {
qDebug() << "No active drag to end";
return;
}
qDebug() << "Drag was active on segment:" << m_dragData.segmentIndex;
// 验证和修复路径
validateAndFixPath();
// 重置状态
m_dragData.isActive = false;
m_dragData.segmentIndex = -1;
m_dragData.isVertical = false;
m_dragData.startScenePos = QPointF();
m_dragData.originalPath = QPainterPath();
// 恢复光标
setCursor(Qt::ArrowCursor);
// 确保场景更新
update();
qDebug() << "✓ Drag ended successfully";
qDebug() << QString(50, '=') << "\n";
}
void ElectricConnectLineItem::setLastPoint(const QPointF& point)
{
m_lastPoint = point;
}
void ElectricConnectLineItem::setPath(const QPainterPath& path)
{
qDebug() << "\n=== setPath ===";
if (m_points == path) {
return;
}
prepareGeometryChange();
m_points = path; // 使用已有的 m_points
updateBoundingRect();
update();
}
QPainterPath ElectricConnectLineItem::shape() const
{
QPainterPath path;
//path.addPath(m_points);
path.addPath(m_pointsBoundingRect);
return path;
// 使用路径的轮廓
if (m_points.isEmpty()) {
return QPainterPath();
}
QPainterPathStroker stroker;
stroker.setWidth(8.0); // 选择区域宽度
QPainterPath shape = stroker.createStroke(m_points);
return shape;
}
QRectF ElectricConnectLineItem::boundingRect() const
{
return m_boundingRect;
QRectF rect = shape().boundingRect();
// 如果shape为空使用路径边界
if (rect.isNull() && !m_points.isEmpty()) {
rect = m_points.boundingRect().adjusted(-5, -5, 5, 5);
}
return rect;
}
void ElectricConnectLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
@ -111,245 +272,6 @@ void ElectricConnectLineItem::paint(QPainter* painter, const QStyleOptionGraphic
painter->drawPath(m_points);
}
void ElectricConnectLineItem::moveLine(QPointF pos)
{
QPointF delta = pos - m_lastPoint;
if(_curLine.isNull())
{
if(m_lstPoints.size() > 1)
{
int n = m_lstPoints.size();
for(int i = 0;i < m_lstPoints.size() -1;++i)
{
QPointF p1 = m_lstPoints[i];
QPointF p2 = m_lstPoints[i+1];
if(p1.x() == p2.x() && abs(p1.x() - pos.x()) < 2) //在相同竖线
{
if(p1.y() > p2.y())
{
if(pos.y() > p2.y() && pos.y() < p1.y()) //在竖线上
{
if(i == 0 ) //起点是连接点,创建复制点
{
m_lstPoints.prepend(p1);
m_lstPoints.prepend(p1);
i+=2;
if(m_lstPoints.size() < 6) //补齐后端
{
m_lstPoints.append(m_lstPoints.last());
}
}
if(i+1 == n-1) //终点是连接点,创建复制点
{
m_lstPoints.append(p2);
m_lstPoints.append(p2);
m_lstPoints[i+1] = p2;
if(m_lstPoints.size() < 6) //补齐前端,移动后至少6个点
{
m_lstPoints.prepend(m_lstPoints.first());
i+=1;
}
}
//qDebug() << 1 <<" "<<i;
_curLine = QPoint(i,1);
break;
}
}
else if(p1.y() < p2.y())
{
if(pos.y() < p2.y() && pos.y() > p1.y()) //在竖线上
{
if(i == 0) //起点是连接点,创建复制点
{
m_lstPoints.prepend(p1);
m_lstPoints.prepend(p1);
i+=2;
if(m_lstPoints.size() < 6) //补齐后端
{
m_lstPoints.append(m_lstPoints.last());
}
}
if(i+1 == n-1) //终点是连接点,创建复制点
{
m_lstPoints.append(p2);
m_lstPoints.append(p2);
m_lstPoints[i+1] = p2;
if(m_lstPoints.size() < 6) //补齐前端
{
m_lstPoints.prepend(m_lstPoints.first());
i+=1;
}
}
//qDebug() << 2 <<" "<<i;
_curLine = QPoint(i,1);
break;
}
}
}
else if(p1.y() == p2.y() && abs(p1.y() - pos.y()) < 2) //在相同横线
{
if(p1.x() > p2.x())
{
if(pos.x() > p2.x() && pos.x() < p1.x())
{
if(i == 0) //起点是连接点,创建复制点
{
m_lstPoints.prepend(p1);
m_lstPoints.prepend(p1);
i+=2;
if(m_lstPoints.size() < 6) //补齐后端
{
m_lstPoints.append(m_lstPoints.last());
}
}
if(i+1 == n-1) //终点是连接点,创建复制点
{
m_lstPoints.append(p2);
m_lstPoints.append(p2);
if(m_lstPoints.size() < 6) //补齐前端,移动后至少6个点
{
m_lstPoints.prepend(m_lstPoints.first());
i+=1;
}
}
//qDebug() << 3 <<" "<<i;
_curLine = QPoint(i,-1);
break;
}
}
else if(p1.x() < p2.x())
{
if(pos.x() < p2.x() && pos.x() > p1.x())
{
if(i == 0) //起点是连接点,创建复制点
{
m_lstPoints.prepend(p1);
m_lstPoints.prepend(p1);
i+=2;
m_lstPoints[i] = p1;
if(m_lstPoints.size() < 6) //补齐后端
{
m_lstPoints.append(m_lstPoints.last());
}
}
if(i+1 == n-1) //终点是连接点,创建复制点
{
m_lstPoints.append(p2);
m_lstPoints.append(p2);
if(m_lstPoints.size() < 6) //补齐前端
{
m_lstPoints.prepend(m_lstPoints.first());
i+=1;
}
}
//qDebug() << 4 <<" "<<i;
_curLine = QPoint(i,-1);
break;
}
}
}
}
}
}
else
{
int n = _curLine.x();
//qDebug() << n <<" "<<_curLine.y();
//if(m_lstPoints.size() > 3)
{
if(_curLine.y() == 1) //竖线
{
if(n == 0) //起点是原点
{
QPointF p(0,delta.y()); //原点不动
m_lstPoints[n +1] = m_lstPoints[n +1] + p; //第二个点只竖直移动
m_lstPoints[n +2] = m_lstPoints[n +2] + p; //第三个点只竖直移动
}
else if(n == 1)
{
QPointF p(delta.x(),0);
m_lstPoints[n] += p; //第一个点只水平移动
m_lstPoints[n +1] += p; //第二个点只水平移动
}
else if(n == m_lstPoints.size()-2) //起点是倒数第二个点
{
QPointF p(0,delta.y());
m_lstPoints[n] += p; //起点只上下移动
m_lstPoints[n-1] += p; //上个点只竖直移动
}
else if(n == m_lstPoints.size()-3) //起点是倒数第三个点
{
QPointF py(0,delta.y());
QPointF px(delta.x(),0);
m_lstPoints[n-1] += py; //上个点只垂直移动
m_lstPoints[n] += delta; //起点任意动
m_lstPoints[n+1] += px; //第二个点只水平移动
}
else
{
m_lstPoints[n -1].setY(m_lstPoints[n ].y());
m_lstPoints[n] += delta;
m_lstPoints[n +1] += delta;
m_lstPoints[n +2].setY(m_lstPoints[n +1].y());
}
}
else //横线
{
if(n == 0) //起点是原点
{
QPointF p(delta.x(),0); //原点不动
m_lstPoints[n +1] = m_lstPoints[n +1] + p; //第二个点只水平移动
m_lstPoints[n +2] = m_lstPoints[n +2] + p; //第三个点只水平移动
}
else if(n == 1)
{
QPointF p(0,delta.y());
m_lstPoints[n] = m_lstPoints[n] + p; //第一个点只竖直移动
m_lstPoints[n +1] = m_lstPoints[n +1] + p; //第二个点只竖直移动
}
else if(n == m_lstPoints.size()-2) //起点是倒数第二个点
{
QPointF p(delta.x(),0);
m_lstPoints[n] += p; //起点水平移动
m_lstPoints[n-1] += p; //上个点只水平移动
}
else if(n == m_lstPoints.size()-3) //起点是倒数第三个点
{
QPointF py(0,delta.y());
QPointF px(delta.x(),0);
m_lstPoints[n-1] += px; //上个点只水平移动
m_lstPoints[n] += delta; //起点任意动
m_lstPoints[n+1] += py; //第二个点只上下移动
}
else
{
m_lstPoints[n -1].setX(m_lstPoints[n].x());
m_lstPoints[n] += delta;
m_lstPoints[n +1] += delta;
m_lstPoints[n +2].setX(m_lstPoints[n +1].x());
}
}
}
calculatePath();
}
m_lastPoint = pos;
}
void ElectricConnectLineItem::calculatePath()
{
if (m_lstPoints.size() < 2) return;
@ -366,7 +288,7 @@ void ElectricConnectLineItem::calculatePath()
qDebug() << "Initialized path, current position:" << m_points.currentPosition();
// 获取元件
QList<QRectF> components = getComponentCollisionRects();
QList<QRectF> components = getAllComponentRects();
qDebug() << "Found" << components.size() << "components";
// 检查起点终点距离
@ -452,7 +374,7 @@ double ElectricConnectLineItem::calculatePathLength(const QList<QPointF>& path)
// 单一线段与矩形相交检测
bool ElectricConnectLineItem::lineIntersectsRect(const QLineF& line, const QRectF& rect)
bool ElectricConnectLineItem::lineIntersectsRect(const QLineF& line, const QRectF& rect) const
{
// 检查端点是否在矩形内
if (rect.contains(line.p1()) || rect.contains(line.p2())) {
@ -690,3 +612,375 @@ QRectF ElectricConnectLineItem::findFirstBlockingComponent(const QPointF& start,
return QRectF();
}
double ElectricConnectLineItem::distancePointToLine(const QLineF& line, const QPointF& point) const
{
// 向量法计算点到线段的最短距离
if (line.isNull()) {
return QLineF(point, line.p1()).length();
}
QPointF v = line.p2() - line.p1(); // 线段向量
QPointF w = point - line.p1(); // 点到线段起点的向量
// 计算点积
double c1 = w.x() * v.x() + w.y() * v.y(); // w·v
if (c1 <= 0.0) {
// 点在线段起点后方
return QLineF(point, line.p1()).length();
}
double c2 = v.x() * v.x() + v.y() * v.y(); // v·v
if (c2 <= c1) {
// 点在线段终点前方
return QLineF(point, line.p2()).length();
}
// 计算投影点
double b = c1 / c2;
QPointF projection = line.p1() + b * v;
return QLineF(point, projection).length();
}
void ElectricConnectLineItem::ensureEnoughPointsForDrag()
{
qDebug() << "\n=== ensureEnoughPointsForDrag ===";
qDebug() << "Current points:" << m_lstPoints.size();
if (m_lstPoints.size() < 2) {
qWarning() << "Not enough points!";
return;
}
// 如果是只有2个点的直线需要添加转折点
if (m_lstPoints.size() == 2) {
QPointF start = m_lstPoints[0];
QPointF end = m_lstPoints[1];
// 如果是斜线,添加转折点
if (start.x() != end.x() && start.y() != end.y()) {
QPointF turnPoint;
// 选择转折方式
if (qAbs(end.x() - start.x()) < qAbs(end.y() - start.y())) {
// 接近垂直,先水平
turnPoint = QPointF(end.x(), start.y());
} else {
// 接近水平,先垂直
turnPoint = QPointF(start.x(), end.y());
}
m_lstPoints.insert(1, turnPoint);
qDebug() << "Added turn point:" << turnPoint;
qDebug() << "Now have" << m_lstPoints.size() << "points";
// 重新计算路径
calculatePath();
}
}
}
void ElectricConnectLineItem::debugPathState(const QString& context) const
{
qDebug() << "\n=== Debug Path State:" << context << "===";
qDebug() << "m_lstPoints count:" << m_lstPoints.size();
qDebug() << "m_dragState.isDragging:" << m_dragData.isActive;
qDebug() << "m_dragState.segmentIndex:" << m_dragData.segmentIndex;
qDebug() << "m_dragState.isVertical:" << m_dragData.isVertical;
for (int i = 0; i < m_lstPoints.size(); i++) {
qDebug() << QString(" Point[%1]: (%2, %3)")
.arg(i)
.arg(m_lstPoints[i].x(), 0, 'f', 1)
.arg(m_lstPoints[i].y(), 0, 'f', 1);
}
// 检查每个线段
for (int i = 0; i < m_lstPoints.size() - 1; i++) {
QPointF p1 = m_lstPoints[i];
QPointF p2 = m_lstPoints[i + 1];
bool isVertical = qFuzzyCompare(p1.x(), p2.x());
bool isHorizontal = qFuzzyCompare(p1.y(), p2.y());
QString type = "DIAGONAL";
if (isVertical) type = "VERTICAL";
else if (isHorizontal) type = "HORIZONTAL";
qDebug() << QString(" Segment[%1]: %2, length=%3")
.arg(i)
.arg(type)
.arg(QLineF(p1, p2).length(), 0, 'f', 1);
}
}
QVector<QLineF> ElectricConnectLineItem::extractSegmentsFromPainterPath() const
{
QVector<QLineF> segments;
if (m_points.isEmpty()) {
return segments;
}
// 遍历QPainterPath的所有元素
QPointF lastPoint;
bool hasLastPoint = false;
for (int i = 0; i < m_points.elementCount(); i++) {
QPainterPath::Element elem = m_points.elementAt(i);
QPointF currentPoint(elem.x, elem.y);
switch (elem.type) {
case QPainterPath::MoveToElement:
lastPoint = currentPoint;
hasLastPoint = true;
break;
case QPainterPath::LineToElement:
if (hasLastPoint) {
segments.append(QLineF(lastPoint, currentPoint));
}
lastPoint = currentPoint;
hasLastPoint = true;
break;
case QPainterPath::CurveToElement:
// 处理曲线(如果需要)
break;
case QPainterPath::CurveToDataElement:
// 曲线数据
break;
}
}
return segments;
}
int ElectricConnectLineItem::findSegmentAt(const QList<QPointF>& points,
const QPointF& itemPos) const
{
if (points.size() < 2) {
return -1;
}
const double HIT_TOLERANCE = 10.0;
int bestSegment = -1;
double bestDistance = HIT_TOLERANCE;
for (int i = 0; i < points.size() - 1; i++) {
QLineF segment(points[i], points[i + 1]);
// 计算距离
double distance = distanceToSegment(segment, itemPos);
if (distance < bestDistance) {
bestDistance = distance;
bestSegment = i;
}
}
return bestSegment;
}
double ElectricConnectLineItem::distanceToSegment(const QLineF& segment, const QPointF& point) const
{
if (segment.isNull()) {
return std::numeric_limits<double>::max();
}
// 检查是否是正交线段
bool isHorizontal = qFuzzyCompare(segment.y1(), segment.y2());
bool isVertical = qFuzzyCompare(segment.x1(), segment.x2());
if (isHorizontal) {
// 水平线段
double minX = qMin(segment.x1(), segment.x2());
double maxX = qMax(segment.x1(), segment.x2());
double y = segment.y1();
if (point.x() >= minX && point.x() <= maxX) {
return qAbs(point.y() - y);
} else if (point.x() < minX) {
return QLineF(point, QPointF(minX, y)).length();
} else {
return QLineF(point, QPointF(maxX, y)).length();
}
}
else if (isVertical) {
// 垂直线段
double minY = qMin(segment.y1(), segment.y2());
double maxY = qMax(segment.y1(), segment.y2());
double x = segment.x1();
if (point.y() >= minY && point.y() <= maxY) {
return qAbs(point.x() - x);
} else if (point.y() < minY) {
return QLineF(point, QPointF(x, minY)).length();
} else {
return QLineF(point, QPointF(x, maxY)).length();
}
}
else {
// 斜线(理论上不应该出现)
return QLineF(segment.p1(), point).length();
}
}
QList<QPointF> ElectricConnectLineItem::extractPointsFromPath() const
{
QList<QPointF> points;
if (m_points.isEmpty()) {
return points;
}
// 从 QPainterPath 提取所有点
for (int i = 0; i < m_points.elementCount(); i++) {
QPainterPath::Element elem = m_points.elementAt(i);
if (elem.type == QPainterPath::MoveToElement ||
elem.type == QPainterPath::LineToElement) {
points.append(QPointF(elem.x, elem.y));
}
}
return points;
}
QList<QPointF> ElectricConnectLineItem::extractPointsFromPath(const QPainterPath& path) const
{
QList<QPointF> points;
if (path.isEmpty()) {
return points;
}
for (int i = 0; i < path.elementCount(); i++) {
QPainterPath::Element elem = path.elementAt(i);
if (elem.type == QPainterPath::MoveToElement ||
elem.type == QPainterPath::LineToElement) {
points.append(QPointF(elem.x, elem.y));
}
}
return points;
}
void ElectricConnectLineItem::applyPointsToPath(const QList<QPointF>& points)
{
if (points.size() < 2) {
m_points = QPainterPath();
return;
}
QPainterPath newPath;
newPath.moveTo(points.first());
for (int i = 1; i < points.size(); i++) {
newPath.lineTo(points[i]);
}
m_points = newPath;
setPath(m_points);
}
void ElectricConnectLineItem::fixConnections(QList<QPointF>& points,
int segmentIndex, bool isVertical)
{
int n = points.size();
if (n < 3) {
return;
}
if (isVertical) {
// 垂直线段移动
if (segmentIndex > 0) {
points[segmentIndex - 1].setX(points[segmentIndex].x());
}
if (segmentIndex + 2 < n) {
points[segmentIndex + 2].setX(points[segmentIndex + 1].x());
}
} else {
// 水平线段移动
if (segmentIndex > 0) {
points[segmentIndex - 1].setY(points[segmentIndex].y());
}
if (segmentIndex + 2 < n) {
points[segmentIndex + 2].setY(points[segmentIndex + 1].y());
}
}
}
void ElectricConnectLineItem::validateAndFixPath()
{
qDebug() << "Validating and fixing path...";
QList<QPointF> points = extractPointsFromPath();
if (points.size() < 2) {
qWarning() << "Path has less than 2 points";
return;
}
bool needsFix = false;
// 检查每个线段
for (int i = 0; i < points.size() - 1; i++) {
QPointF& p1 = points[i];
QPointF& p2 = points[i + 1];
// 检查是否正交
if (!qFuzzyCompare(p1.x(), p2.x()) && !qFuzzyCompare(p1.y(), p2.y())) {
qDebug() << "Fixing non-orthogonal segment" << i;
// 选择主要方向
double dx = qAbs(p2.x() - p1.x());
double dy = qAbs(p2.y() - p1.y());
if (dx < dy) {
p2.setX(p1.x()); // 改为垂直
} else {
p2.setY(p1.y()); // 改为水平
}
needsFix = true;
}
}
// 移除连续重复点
QList<QPointF> cleanedPoints;
cleanedPoints.append(points.first());
for (int i = 1; i < points.size(); i++) {
if (!points[i - 1].isNull() &&
qFuzzyCompare(points[i - 1].x(), points[i].x()) &&
qFuzzyCompare(points[i - 1].y(), points[i].y())) {
continue; // 跳过重复点
}
cleanedPoints.append(points[i]);
}
if (needsFix || cleanedPoints.size() != points.size()) {
qDebug() << "Applying fixes to path";
applyPointsToPath(cleanedPoints);
// 重新计算路径
calculatePath();
}
}
void ElectricConnectLineItem::updateBoundingRect()
{
if (m_points.isEmpty()) {
m_boundingRect = QRectF();
} else {
// 使用路径的边界
m_boundingRect = m_points.boundingRect();
// 添加一些边距
const qreal MARGIN = 2.0;
m_boundingRect.adjust(-MARGIN, -MARGIN, MARGIN, MARGIN);
}
qDebug() << "Updated bounds:" << m_boundingRect;
}

View File

@ -398,7 +398,7 @@ void GraphicsBaseItem::rearrangeDynamicText()
}
}
QList<QRectF> GraphicsBaseItem::getComponentCollisionRects() const
QList<QRectF> GraphicsBaseItem::getAllComponentRects() const
{
QList<QRectF> lst;
if(_pHandle){

View File

@ -282,10 +282,10 @@ void MonitorPanel::loadNodes(QJsonObject obj)
}
QJsonArray relationArr = obj["relation"].toArray();
QList<monitorRelationItem> lstRelation;
QList<RelationItem> lstRelation;
bool resRel = deserializeRelationFromJsonArray(relationArr, lstRelation);
if(resRel){
QList<monitorRelationItem> lstFirst;
QList<RelationItem> lstFirst;
if(_pModel){
auto pItems = _pModel->getProjectItems();
for(auto& itemInfo:lstRelation)
@ -299,7 +299,7 @@ void MonitorPanel::loadNodes(QJsonObject obj)
}
}
QList<monitorRelationItem> lstSecond;
QList<RelationItem> lstSecond;
for(auto& itemInfo:lstRelation) //第二次循环处理间隔内设备
{
if(itemInfo.item.nCategory == 0){ //间隔
@ -324,7 +324,7 @@ void MonitorPanel::saveNodes(int pageId)
}
void MonitorPanel::updateSelectedItems(QList<monitorRelationItem> lst,bool val)
void MonitorPanel::updateSelectedItems(QList<RelationItem> lst,bool val)
{
if(val){
QStandardItem *root = _itemListmodel->invisibleRootItem();
@ -625,7 +625,7 @@ void MonitorPanel::initDisplaySetting()
}
}
QJsonArray MonitorPanel::serializeRelationToJsonArray(const QList<monitorRelationItem>& data) const
QJsonArray MonitorPanel::serializeRelationToJsonArray(const QList<RelationItem>& data) const
{
QJsonArray rootArray;
@ -637,14 +637,14 @@ QJsonArray MonitorPanel::serializeRelationToJsonArray(const QList<monitorRelatio
}
// 从 QJsonArray 反序列化到 QList<monitorRelationItem>
bool MonitorPanel::deserializeRelationFromJsonArray(const QJsonArray& jsonArray, QList<monitorRelationItem>& result)
bool MonitorPanel::deserializeRelationFromJsonArray(const QJsonArray& jsonArray, QList<RelationItem>& result)
{
result.clear();
for (const QJsonValue& itemValue : jsonArray) {
if (!itemValue.isObject()) continue;
monitorRelationItem relationItem;
RelationItem relationItem;
relationItem.fromJson(itemValue.toObject());
if (relationItem.isValid()) {

View File

@ -7,7 +7,7 @@
#include <QCompleter>
#include <QStringListModel>
#include "titleBar.h"
#include "instance/extraPropertyManager.h"
#include "extraPropertyManager.h"
#include "structDataSource.h"
#include "structDataMeasurementModel.h"
#include "structDataPropertyModel.h"

View File

@ -292,7 +292,6 @@ void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene
{
if(item->getItemType() == GIT_bay)
return;
item->setPosition(item->pos());
if(ms_nDragHandle == H_none)
{
//设置光标样式
@ -475,12 +474,12 @@ void BaseSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerSc
view->setDragMode(QGraphicsView::NoDrag);
}
QList<monitorRelationItem> lst; //发送已选中的元件
QList<RelationItem> lst; //发送已选中的元件
QList<QGraphicsItem *> items = scene->selectedItems();
for(auto& pItem:items){
GraphicsProjectModelItem* item = dynamic_cast<GraphicsProjectModelItem*>(pItem);
if(item){
monitorRelationItem info;
RelationItem info;
auto pPro = item->getProperty();
if(pPro){
info.item.nCategory = 0;
@ -493,7 +492,7 @@ void BaseSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerSc
else{
GraphicsNonStandardItem* bay = dynamic_cast<GraphicsNonStandardItem*>(pItem);
if(bay){
monitorRelationItem info;
RelationItem info;
auto pBayPro = bay->getProperty();
if(pBayPro){
info.item.nCategory = 1;

View File

@ -17,31 +17,23 @@ LinkMovingSelector::~LinkMovingSelector()
void LinkMovingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
{
ms_ptMouseLast = event->scenePos();
//QList<QGraphicsItem *> items = scene->selectedItems();
}
void LinkMovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
{
ms_ptMouseLast = event->scenePos();
if(m_pMovingLine == nullptr)
{
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1) //只有一个选中
{
if (m_pMovingLine == nullptr) {
QList<QGraphicsItem*> items = scene->selectedItems();
if (items.count() == 1) {
ElectricConnectLineItem* item = qgraphicsitem_cast<ElectricConnectLineItem*>(items.first());
if(item)
{
if (item) {
m_pMovingLine = item;
item->setLastPoint(ms_ptMouseLast);
m_pMovingLine->startDrag(event->scenePos());
qDebug() << "Started drag on line at:" << event->scenePos();
}
}
}
else
{
//if(m_pMovingLine)
//m_pMovingLine->moveLine(ms_ptMouseLast); //暂时屏蔽移动线 260204
} else {
m_pMovingLine->updateDrag(event->scenePos());
}
}
@ -50,8 +42,7 @@ void LinkMovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Desi
{
if(m_pMovingLine)
{
m_pMovingLine->resetCurLine();
qDebug()<<"reset";
m_pMovingLine->endDrag();
}
m_pMovingLine = nullptr;
ms_nDragHandle = H_none;

View File

@ -42,7 +42,7 @@ void MovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerSce
void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
{
QList<monitorRelationItem> lst; //发送已选中的元件
QList<RelationItem> lst; //发送已选中的元件
QList<QGraphicsItem *> items = scene->selectedItems();
for(int n = 0; n < items.size(); n++)
{
@ -53,7 +53,7 @@ void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Designer
GraphicsProjectModelItem* p = dynamic_cast<GraphicsProjectModelItem*>(items.at(n));
if(p){
auto pPro = p->getProperty();
monitorRelationItem info;
RelationItem info;
if(pPro){
info.item.nCategory = 0;
info.item.nEquipType = pPro->type();
@ -65,7 +65,7 @@ void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Designer
else{
GraphicsNonStandardItem* bay = dynamic_cast<GraphicsNonStandardItem*>(items.at(n));
if(bay){
monitorRelationItem info;
RelationItem info;
auto pBayPro = bay->getProperty();
if(pBayPro){
info.item.nCategory = 1;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>650</width>
<height>460</height>
<width>605</width>
<height>580</height>
</rect>
</property>
<property name="font">

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>650</width>
<height>460</height>
<width>605</width>
<height>580</height>
</rect>
</property>
<property name="font">
@ -18,7 +18,7 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1,1,0">
<property name="leftMargin">
<number>0</number>
</property>
@ -165,37 +165,6 @@ QPushButton:disabled {
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_preview">
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
color: white;
border: none; /* 无边框,扁平化 */
border-radius: 4px; /* 小圆角,扁平感 */
font-size: 13px; /* 适中字号 */
font-weight: 500; /* 中等字重 */
}
QPushButton:hover {
background-color: #4a5d7e; /* 稍深的灰蓝 */
}
QPushButton:pressed {
background-color: #3d4e6b; /* 更深的灰蓝 */
}
QPushButton:disabled {
background-color: #a0b3d1; /* 灰调的浅蓝 */
color: #d1dce9; /* 浅灰色文字 */
}
</string>
</property>
<property name="text">
<string>预览间隔</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -211,6 +180,13 @@ QPushButton:disabled {
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_preview">
<property name="title">
<string>结构预览</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="maximumSize">

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>650</width>
<height>460</height>
<width>605</width>
<height>580</height>
</rect>
</property>
<property name="font">
@ -18,7 +18,7 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1,1,0">
<property name="leftMargin">
<number>0</number>
</property>
@ -134,6 +134,27 @@ QWidget QLabel {
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>预览模式:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cb_previewType">
<item>
<property name="text">
<string>中性点</string>
</property>
</item>
<item>
<property name="text">
<string>变压器</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
@ -178,68 +199,6 @@ QPushButton:disabled {
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_previewEquips">
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
color: white;
border: none; /* 无边框,扁平化 */
border-radius: 4px; /* 小圆角,扁平感 */
font-size: 13px; /* 适中字号 */
font-weight: 500; /* 中等字重 */
}
QPushButton:hover {
background-color: #4a5d7e; /* 稍深的灰蓝 */
}
QPushButton:pressed {
background-color: #3d4e6b; /* 更深的灰蓝 */
}
QPushButton:disabled {
background-color: #a0b3d1; /* 灰调的浅蓝 */
color: #d1dce9; /* 浅灰色文字 */
}
</string>
</property>
<property name="text">
<string>预览成套装置</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_previewTrans">
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
color: white;
border: none; /* 无边框,扁平化 */
border-radius: 4px; /* 小圆角,扁平感 */
font-size: 13px; /* 适中字号 */
font-weight: 500; /* 中等字重 */
}
QPushButton:hover {
background-color: #4a5d7e; /* 稍深的灰蓝 */
}
QPushButton:pressed {
background-color: #3d4e6b; /* 更深的灰蓝 */
}
QPushButton:disabled {
background-color: #a0b3d1; /* 灰调的浅蓝 */
color: #d1dce9; /* 浅灰色文字 */
}
</string>
</property>
<property name="text">
<string>预览变压器</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
@ -329,6 +288,13 @@ QTabBar::tab:selected {
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_preview">
<property name="title">
<string>结构预览</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="maximumSize">

View File

@ -19,12 +19,12 @@ public:
void initial();
signals:
void generateMonitor(QString,QList<monitorRelationItem>); //生成监控
void generateMonitor(QString,QList<RelationItem>); //生成监控
public slots:
void onUpdateItems(QList<monitorRelationItem>,bool refresh); //更新当前设备列表
void onSelectItems(QList<monitorRelationItem>); //更新当前选中的设备
void onUpdateItems(QList<RelationItem>,bool refresh); //更新当前设备列表
void onSelectItems(QList<RelationItem>); //更新当前选中的设备
void onGenerateClicked();
void onMonitorCreated(QList<monitorRelationItem>); //创建后的设备列表
void onMonitorCreated(QList<RelationItem>); //创建后的设备列表
void onItemChanged(QStandardItem *item); //item勾选事件
private:
void resetSelect(); //重置选中
@ -34,10 +34,15 @@ private:
QList<QStandardItem*> getCheckedItems(QStandardItem* parentItem); //返回checked对象
QList<QStandardItem*> getTreeViewCheckedItems(QTreeView* treeView); //返回checked对象
// 查找间隔节点
QStandardItem* findBayItem(const QString& bayName);
private:
Ui::monitorItemsDlg *ui;
QStandardItemModel* _modelAll; //图中所有item
QStandardItemModel* _modelSelect; //生成的item
// 存储间隔名称到树节点的映射,提高查找效率
QHash<QString, QStandardItem*> m_mapBayItems;
};
#endif

View File

@ -10,6 +10,8 @@ namespace Ui { class topologyView; }
QT_END_NAMESPACE
class TopologyTree;
class ExtraPropertyManager;
class StructDataSource;
class TopologyView : public QDialog
{
@ -27,18 +29,27 @@ signals:
void entityDelete(EntityInfo);
void entitySelected(EntityInfo);
public slots:
void onIndexRbtnClicked(const QPoint &pos); //索引列表右键菜单
void onItemChanged(QStandardItem *item);
void onItemClicked(const QModelIndex &index);
void onDataCreated(QString uuid);
void onDataChanged(QString uuid);
void onUpdateTopology(QList<RelationItem> lst,bool refresh);
private:
void addItemToView(QString sGrid,QString sZone,QString sStation,QStandardItem *root,QStandardItem *item);
void clearItems();
QString getLevelType(int index);
void buildTreeStructure(QStandardItemModel* model, const QVector<ExtraProperty>& properties);
QVector<ExtraProperty> getPropertiesForNode(QStandardItem* node);
QString getNodeInfo(QStandardItem* node);
QStandardItem* findBayItem(const QString& voltageLevel, const QString& bayName);
QStandardItem* findOrCreateVoltageLevel(const QString& voltageLevel); // 查找或创建电压层级节点
QStandardItem* createBayItem(const QString& voltageLevel, const RelationSturctItem& bayInfo);
void createDeviceItem(QStandardItem* pParent, const RelationSturctItem& deviceInfo); // 创建设备节点
private:
Ui::topologyView *ui;
QStandardItemModel* _pModel;
QStandardItemModel* _treeModel;
ExtraPropertyManager* _pExtraProManager;
StructDataSource* m_dataSource;
TopologyTree* _treeView;
QHash<QString, QStandardItem*> m_mapVoltageLevels; // 存储电压层级名称到树节点的映射
QHash<QString, QStandardItem*> m_mapBayItems; // 存储间隔节点key格式为"电压层级|间隔名称"
};
#endif

View File

@ -175,6 +175,8 @@ void CMainWindow::initializeAction()
connect(m_pTopologyView,&TopologyView::entityDelete,m_pDiagramCavas,&DiagramCavas::onSignal_deleteEntity);
connect(m_pTopologyView,&TopologyView::entitySelected,m_pDiagramCavas,&DiagramCavas::onSignal_selectEntity);
connect(m_pDiagramCavas,&DiagramCavas::prepareUpdateTopology,m_pTopologyView,&TopologyView::onUpdateTopology);
//connect(m_pDiagramView,&DiagramView::diagramCreate,m_pDiagramCavas,&DiagramCavas::onSignal_createDiagram);
connect(m_pDiagramView,&DiagramView::diagramChange,m_pDiagramCavas,&DiagramCavas::onSignal_changeDiagram);
connect(m_pDiagramView,&DiagramView::diagramDelete,m_pDiagramCavas,&DiagramCavas::onSignal_deleteDiagram);

View File

@ -33,61 +33,74 @@ void MonitorItemsDlg::initial()
connect(_modelAll, &QStandardItemModel::itemChanged,this, &MonitorItemsDlg::onItemChanged);
}
void MonitorItemsDlg::onUpdateItems(QList<monitorRelationItem> lst,bool refresh)
void MonitorItemsDlg::onUpdateItems(QList<RelationItem> lst,bool refresh)
{
if(refresh){
QStandardItem *root = _modelAll->invisibleRootItem();
int rowCount = root->rowCount();
if (rowCount > 0) {
_modelAll->removeRows(0, rowCount);
}
// 清空间隔节点缓存
m_mapBayItems.clear();
}
// 先处理间隔节点nCategory == 1
for(auto &info:lst){
auto curItem = info.item;
if(curItem.nCategory == 0){
if(curItem.nCategory == 1){ // 间隔信息
// 查找是否已存在该间隔节点
QStandardItem* pBayItem = findBayItem(curItem.sName);
if(!pBayItem){
// 创建间隔节点
pBayItem = new QStandardItem(curItem.sName);
pBayItem->setCheckable(true); // 启用勾选框
pBayItem->setCheckState(Qt::Unchecked);
pBayItem->setData(curItem.nCategory, Qt::UserRole+1); // 存储类别
pBayItem->setData(curItem.nEquipType, Qt::UserRole+2); // 存储设备类型
pBayItem->setData(curItem.uid, Qt::UserRole+3); // 存储UUID
if(curItem.nEquipType == 1 || curItem.nEquipType == 15 || curItem.nEquipType == 16){ //母线与变压器等间隔外设备并列第一层
QStandardItem *pItem = new QStandardItem(curItem.sName);
pItem->setCheckable(true); // 启用勾选框
pItem->setCheckState(Qt::Unchecked);
pItem->setData(curItem.nCategory,Qt::UserRole+1);
pItem->setData(curItem.nEquipType,Qt::UserRole+2);
pItem->setData(curItem.uid,Qt::UserRole+3);
for(auto& subInfo:info.subList){ //母线挂接间隔,变压器挂接设备
QStandardItem *pSub = new QStandardItem(subInfo.sName);
pSub->setCheckable(true); // 启用勾选框
pSub->setCheckState(Qt::Unchecked);
pSub->setData(subInfo.nCategory,Qt::UserRole+1);
pSub->setData(subInfo.nEquipType,Qt::UserRole+2);
pSub->setData(subInfo.uid,Qt::UserRole+3);
pItem->appendRow(pSub);
}
_modelAll->appendRow(pItem);
// 存储到缓存中
m_mapBayItems[curItem.sName] = pBayItem;
_modelAll->appendRow(pBayItem);
}
else{ //其他设备挂接在母线下的间隔中
if(!info.parent.sName.isEmpty()){ //有父,在间隔内
}
}
// 再处理设备节点nCategory == 0
for(auto &info:lst){
auto curItem = info.item;
if(curItem.nCategory == 0){ // 设备信息
// 获取设备所属的间隔名称
QString bayName = info.parent.sName;
if(!bayName.isEmpty()){
// 查找对应的间隔节点
QStandardItem* pBayItem = findBayItem(bayName);
if(pBayItem){
// 创建设备节点
QStandardItem *pItem = new QStandardItem(curItem.sName);
pItem->setCheckable(true); // 启用勾选框
pItem->setCheckState(Qt::Unchecked);
pItem->setData(curItem.nCategory,Qt::UserRole+1);
pItem->setData(curItem.nEquipType,Qt::UserRole+2);
pItem->setData(curItem.uid,Qt::UserRole+3);
pItem->setData(curItem.nCategory, Qt::UserRole+1);
pItem->setData(curItem.nEquipType, Qt::UserRole+2);
pItem->setData(curItem.uid, Qt::UserRole+3);
auto pParent = findStandardItemAtLevel(_modelAll,1,info.parent.sName,nullptr,0); //查找父间隔所在item
if(pParent){
pParent->appendRow(pItem);
}
// 不再为母线或独立设备添加子设备
// 所有设备都作为间隔的直接子节点
pBayItem->appendRow(pItem);
}
}
}
}
// 展开所有节点
ui->treeView_all->expandAll();
}
void MonitorItemsDlg::onSelectItems(QList<monitorRelationItem> lst)
void MonitorItemsDlg::onSelectItems(QList<RelationItem> lst)
{
ui->stackedWidget->setCurrentIndex(0);
resetSelect();
@ -109,10 +122,10 @@ void MonitorItemsDlg::onGenerateClicked()
ui->le_name->setFocus();
return;
}
QList<monitorRelationItem> lst;
QList<RelationItem> lst;
QList<QStandardItem*> lstItem = getTreeViewCheckedItems(ui->treeView_all);
for(auto& pItem:lstItem){
monitorRelationItem info;
RelationItem info;
auto pParent = pItem->parent();
if(pParent){
info.parent.nCategory = pParent->data(Qt::UserRole+1).toInt();
@ -127,7 +140,7 @@ void MonitorItemsDlg::onGenerateClicked()
auto lstChild = getAllChildren(pItem);
for(auto &child:lstChild){
monitorRelationSturctItem stru;
RelationSturctItem stru;
stru.nCategory = child->data(Qt::UserRole+1).toInt();
stru.nEquipType = child->data(Qt::UserRole+2).toInt();
stru.uid = child->data(Qt::UserRole+3).toUuid();
@ -140,7 +153,7 @@ void MonitorItemsDlg::onGenerateClicked()
emit generateMonitor(sName,lst);
}
void MonitorItemsDlg::onMonitorCreated(QList<monitorRelationItem> lst)
void MonitorItemsDlg::onMonitorCreated(QList<RelationItem> lst)
{
/*ui->stackedWidget->setCurrentIndex(1);
ui->listWidget_select->clear();
@ -201,6 +214,24 @@ void MonitorItemsDlg::traverseSelectStandardItem(QStandardItem *item, int depth,
}
}
QStandardItem* MonitorItemsDlg::findBayItem(const QString& bayName)
{
// 先从缓存查找
if(m_mapBayItems.contains(bayName)){
return m_mapBayItems[bayName];
}
// 遍历查找
for(int i = 0; i < _modelAll->rowCount(); ++i){
QStandardItem* pItem = _modelAll->item(i);
if(pItem->text() == bayName &&
pItem->data(Qt::UserRole+1).toInt() == 1){ // 类别为间隔
return pItem;
}
}
return nullptr;
}
QList<QStandardItem*> MonitorItemsDlg::getCheckedItems(QStandardItem* parentItem) {
QList<QStandardItem*> checkedItems;

View File

@ -5,6 +5,8 @@
#include "dataBase.h"
#include "basePropertyManager.h"
#include "baseProperty.h"
#include "structDataSource.h"
#include "extraPropertyManager.h"
#include <QStandardItemModel>
#include <QMenu>
#include <QUuid>
@ -12,12 +14,13 @@
TopologyView::TopologyView(QWidget *parent)
: QDialog(parent)
, ui(new Ui::topologyView)
,_pModel(nullptr)
,_treeModel(nullptr)
,_treeView(nullptr)
,_pExtraProManager(nullptr)
{
ui->setupUi(this);
//setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint&Qt::WindowCloseButtonHint);
_pModel = new QStandardItemModel(this);
_treeModel = new QStandardItemModel(this);
_treeView = new TopologyTree(this);
ui->verticalLayout->addWidget(_treeView);
_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
@ -31,170 +34,47 @@ TopologyView::~TopologyView()
void TopologyView::initial()
{
connect(_treeView, &QTreeView::customContextMenuRequested, this, &TopologyView::onIndexRbtnClicked);
connect(_treeView, &QTreeView::clicked, this, &TopologyView::onItemClicked);
connect(_pModel, &QStandardItemModel::itemChanged, this, &TopologyView::onItemChanged);
connect(&BasePropertyManager::instance(),&BasePropertyManager::dataChanged,this,&TopologyView::onDataChanged);
connect(_treeModel, &QStandardItemModel::itemChanged, this, &TopologyView::onItemChanged);
m_dataSource = new StructDataSource(this);
_pExtraProManager = new ExtraPropertyManager(this);
_pExtraProManager->initial();
if(_pExtraProManager)
m_dataSource->loadExtrapro(_pExtraProManager->geAlltProperty());
_treeView->setHeaderHidden(true);
// 设置模型的列数
_pModel->setColumnCount(1);
// 设置模型的标题
//_pModel->setHeaderData(0, Qt::Horizontal, QObject::tr("层级"));
QStandardItem *rootItem = _pModel->invisibleRootItem();
QList<componentInfo> lst= DataBase::GetInstance()->getAllComponents();
for(auto &info:lst)
{
QString nG= info.grid;
QString nZ = info.zone;
QString nS= info.station;
//QString sGrid = DataBase::GetInstance()->getGridNameById(nG.toInt());
//QString sZone = DataBase::GetInstance()->getZoneNameById(nZ.toInt());
//QString sStation = DataBase::GetInstance()->getStationNameById(nS.toInt());
QString sGrid = nG; //暂时不使用id查找名称
QString sZone = nZ;
QString sStation = nS;
if(info.name.isEmpty())
continue;
QStandardItem *pItem = new QStandardItem(info.name);
pItem->setData(info.uuid.toString(),Qt::UserRole);
addItemToView(sGrid,sZone,sStation,rootItem,pItem);
}
_treeModel->setColumnCount(1);
// 创建树视图
_treeView->setModel(_pModel);
_treeView->setModel(_treeModel);
// 展开所有节点
_treeView->expandAll();
// 显示树视图
_treeView->setWindowTitle(QObject::tr("拓扑树"));
loadTopologyFromDB();
}
void TopologyView::loadTopologyFromDB()
{
}
void TopologyView::onIndexRbtnClicked(const QPoint &pos)
{
// 获取当前点击的位置对应的索引
QModelIndex index = _treeView->indexAt(pos);
if (!index.isValid()) {
return; // 如果点击的是空白区域,直接返回
}
QMenu menu;
QStandardItem* item = _pModel->itemFromIndex(index);
if(item)
if(_pExtraProManager)
{
int nCount = item->rowCount();
int nLevel = getLevel(item);
if(nLevel == -1) //根节点
{
QAction *addAction = new QAction("添加电网", this);
//clearItems();
auto& mapExtra = m_dataSource->allProperties;
/*QStandardItem* root = _treeModel->invisibleRootItem();
for(auto& pro:mapExtra){
QStandardItem* propertyItem = new QStandardItem();
addItemToView(pro,"name",root,propertyItem);
}*/
QVector<ExtraProperty> vec = QVector<ExtraProperty>::fromList(mapExtra.values());
buildTreeStructure(_treeModel,vec);
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *gridItem = new QStandardItem(QString("电网_")+QString::number(nCount));
gridItem->setData(uuid,Qt::UserRole+1);
gridItem->setData(int(EntityType::Grid),Qt::UserRole+2);
item->appendRow(gridItem);
EntityInfo info;
info.eType = EntityType::Grid;
info.sName = gridItem->text();
info.sUuid = uuid;
emit entityCreate(info);
});
menu.addAction(addAction);
}
else if(nLevel == 1) //grid
{
QAction *addAction = new QAction("添加区域", this);
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *zoneItem = new QStandardItem(QString("区域_")+QString::number(nCount));
zoneItem->setData(uuid,Qt::UserRole+1);
zoneItem->setData(int(EntityType::Zone),Qt::UserRole+2);
item->appendRow(zoneItem);
EntityInfo info;
info.eType = EntityType::Zone;
info.sName = zoneItem->text();
info.sParentId = sParentid;
info.sUuid = uuid;
emit entityCreate(info);
_treeView->expandAll();
});
menu.addAction(addAction);
}
else if(nLevel == 2) //zone
{
QAction *addAction = new QAction("添加场站", this);
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *stationItem = new QStandardItem(QString("场站_")+QString::number(nCount));
stationItem->setData(uuid,Qt::UserRole+1);
stationItem->setData(int(EntityType::Station),Qt::UserRole+2);
item->appendRow(stationItem);
EntityInfo info;
info.eType = EntityType::Station;
info.sName = stationItem->text();
info.sUuid = uuid;
info.sParentId = sParentid;
emit entityCreate(info);
_treeView->expandAll();
});
menu.addAction(addAction);
}
if(nLevel != -1) //除了根节点其余都能删除
{
QAction *delAction = new QAction("删除", this);
connect(delAction,&QAction::triggered,this,[&](){
QModelIndex currentIndex = _treeView->currentIndex();
if(currentIndex.isValid())
{
QStandardItem* pItem = _pModel->itemFromIndex(currentIndex);
if(pItem)
{
QString str = item->text();
EntityInfo info;
info.sName = str;
info.sUuid = item->data(Qt::UserRole+1).toString();
info.eType = EntityType(item->data(Qt::UserRole+2).toInt());
emit entityDelete(info);
QStandardItem* pParent = item->parent();
if(pParent)
{
pParent->removeRow(currentIndex.row());
}
}
}
});
menu.addAction(delAction);
}
_treeView->expandAll();
}
// 在点击位置显示菜单
menu.exec(_treeView->mapToGlobal(pos));
}
void TopologyView::onItemChanged(QStandardItem *item)
@ -210,7 +90,7 @@ void TopologyView::onItemChanged(QStandardItem *item)
void TopologyView::onItemClicked(const QModelIndex &index)
{
QStandardItem* item = _pModel->itemFromIndex(index);
QStandardItem* item = _treeModel->itemFromIndex(index);
if(item)
{
EntityType type = EntityType(item->data(Qt::UserRole+2).toInt());
@ -226,99 +106,363 @@ void TopologyView::onItemClicked(const QModelIndex &index)
}
}
void TopologyView::onDataCreated(QString uuid)
void TopologyView::onUpdateTopology(QList<RelationItem> lst,bool refresh)
{
if(refresh){
QStandardItem *root = _treeModel->invisibleRootItem();
int rowCount = root->rowCount();
if (rowCount > 0) {
_treeModel->removeRows(0, rowCount);
}
// 清空缓存
m_mapVoltageLevels.clear();
m_mapBayItems.clear();
}
}
// 第一阶段处理间隔节点nCategory == 1
for(auto &info:lst){
auto curItem = info.item;
if(curItem.nCategory == 1){ // 间隔信息
// 获取间隔的电压层级
QString voltageLevel = curItem.sVoltageLevel;
if(voltageLevel.isEmpty()){
voltageLevel = "未知电压等级"; // 默认值
}
void TopologyView::onDataChanged(QString uuid)
{
QModelIndex itemIndex = findIndex(_pModel,uuid,Qt::UserRole);
BaseProperty* pData = BasePropertyManager::instance().findEntityData(QUuid(uuid));
if(pData)
{
if(itemIndex.isValid()) //已存在
{
QStandardItem *pItem = _pModel->itemFromIndex(itemIndex);
if(pItem)
{
if(pItem->text() != pData->tag()) //已改名
{
pItem->setText(pData->tag());
}
// 查找或创建电压层级节点
QStandardItem* pVoltageItem = findOrCreateVoltageLevel(voltageLevel);
QString sStation = pItem->parent()->text();
QString sZone = pItem->parent()->parent()->text();
QString sGrid = pItem->parent()->parent()->parent()->text();
if(sStation == pData->station() && sZone == pData->zone() && sGrid == pData->grid()) //从属关系未变
{
// 创建间隔节点
QStandardItem* pBayItem = createBayItem(voltageLevel, curItem);
}
else
{
QStandardItem* item = _pModel->takeItem(pItem->row()); //从原层级中取出,添加到新的层级
addItemToView(pData->grid(),pData->zone(),pData->station(),_pModel->invisibleRootItem(),item);
pVoltageItem->appendRow(pBayItem);
}
}
// 第二阶段处理设备节点nCategory == 0
for(auto &info:lst){
auto curItem = info.item;
if(curItem.nCategory == 0){ // 设备信息
// 获取设备所属的间隔名称和电压层级
QString bayName = info.parent.sName;
QString voltageLevel = info.parent.sVoltageLevel; // 从父间隔获取电压层级
if(!bayName.isEmpty() && !voltageLevel.isEmpty()){
// 查找对应的间隔节点
QStandardItem* pBayItem = findBayItem(voltageLevel, bayName);
if(pBayItem){
// 创建设备节点
createDeviceItem(pBayItem, curItem);
}
}
}
else
{
QStandardItem *pItem = new QStandardItem(pData->tag());
pItem->setData(uuid,Qt::UserRole);
addItemToView(pData->grid(),pData->zone(),pData->station(),_pModel->invisibleRootItem(),pItem);
}
// 展开所有节点
_treeView->expandAll();
}
void TopologyView::clearItems()
{
if(_treeModel){
QStandardItem *root = _treeModel->invisibleRootItem(); //先清空model
int rowCount = root->rowCount();
if (rowCount > 0) {
_treeModel->removeRows(0, rowCount);
}
}
}
void TopologyView::addItemToView(QString sGrid,QString sZone,QString sStation,QStandardItem *root,QStandardItem *pItem)
{
QModelIndex iG;
QModelIndex iZ;
QModelIndex iS;
iG = findIndex(_pModel, sGrid, Qt::DisplayRole, QModelIndex());
if (iG.isValid()) {
iZ = findIndex(_pModel, sZone, Qt::DisplayRole, iG); // 只在Grid下查找
if (iZ.isValid()) {
iS = findIndex(_pModel, sStation, Qt::DisplayRole, iZ); // 只在Zone下查找
}
}
if(iG.isValid()) //已创建
{
QStandardItem* itemGrid = _pModel->itemFromIndex(iG);
if(iZ.isValid())
{
QStandardItem* itemZone = _pModel->itemFromIndex(iZ);
if(iS.isValid())
{
QStandardItem* itemStation = _pModel->itemFromIndex(iS);
itemStation->appendRow(pItem);
}
else
{
QStandardItem* itemStation = new QStandardItem(sStation);
itemStation->appendRow(pItem);
itemZone->appendRow(itemStation);
}
}
else
{
QStandardItem* itemZone = new QStandardItem(sZone);
QStandardItem* itemStation = new QStandardItem(sStation);
itemStation->appendRow(pItem);
itemZone->appendRow(itemStation);
itemGrid->appendRow(itemZone);
}
}
else
{
QStandardItem* itemGrid = new QStandardItem(sGrid);
QStandardItem* itemZone = new QStandardItem(sZone);
QStandardItem* itemStation = new QStandardItem(sStation);
itemStation->appendRow(pItem);
itemZone->appendRow(itemStation);
itemGrid->appendRow(itemZone);
root->appendRow(itemGrid);
QString TopologyView::getLevelType(int index) {
switch (index) {
case 0: return "电网";
case 1: return "区域";
case 2: return "站点";
case 3: return "电压等级";
case 4: return "间隔";
case 5: return "设备";
case 6: return "分组";
default: return "未知层级";
}
}
void TopologyView::buildTreeStructure(QStandardItemModel* model,
const QVector<ExtraProperty>& properties) {
// 清空模型
model->clear();
// 创建根节点
//QStandardItem* root = new QStandardItem("拓扑结构");
//model->appendRow(root);
QStandardItem* root = _treeModel->invisibleRootItem();
// 存储节点映射:路径 -> 节点
QMap<QString, QStandardItem*> nodeMap;
for (const auto& property : properties) {
// 判断是否有设备信息
bool hasDevice = !property.component_uuid.isNull() && !property.component_name.isEmpty();
// 检查间隔信息(根据业务逻辑,间隔应该总是存在)
QString bayDisplayName = property.bay_name.isEmpty() ?
(property.bay_tag.isEmpty() ? "未命名间隔" : property.bay_tag) :
property.bay_name;
// 构建完整的节点路径
QStringList pathComponents;
// 基本层级:电网、区域、站点、电压等级、间隔
pathComponents << property.grid_name;
pathComponents << property.zone_name;
pathComponents << property.station_name;
pathComponents << property.currentLevel;
pathComponents << bayDisplayName;
// 如果有设备信息,添加设备层级
if (hasDevice) {
QString deviceDisplayName = property.component_name.isEmpty() ?
property.component_uuid.toString() :
property.component_name;
pathComponents << deviceDisplayName;
}
// 构建路径字符串作为唯一标识
QString pathKey = pathComponents.join("|");
// 查找或创建节点路径
QStandardItem* currentNode = root;
QString currentPath = "";
for (int i = 0; i < pathComponents.size(); i++) {
currentPath += (i > 0 ? "|" : "") + pathComponents[i];
// 查找是否已存在该节点
QStandardItem* existingNode = nodeMap.value(currentPath);
if (!existingNode) {
// 在当前父节点下查找
for (int row = 0; row < currentNode->rowCount(); row++) {
QStandardItem* child = currentNode->child(row, 0);
if (child && child->text() == pathComponents[i]) {
QVariantMap childData = child->data(Qt::UserRole + 1).toMap();
QString childPath = childData.value("fullPath").toString();
if (childPath == currentPath) {
existingNode = child;
nodeMap[currentPath] = child;
break;
}
}
}
}
if (existingNode) {
currentNode = existingNode;
} else {
// 创建新节点
QStandardItem* newNode = new QStandardItem(pathComponents[i]);
// 确定节点类型和层级信息
QVariantMap nodeData;
nodeData["fullPath"] = currentPath;
nodeData["level"] = i;
// 根据层级设置节点类型
QString nodeType;
QString levelType;
switch (i) {
case 0: nodeType = "grid"; levelType = "电网"; break;
case 1: nodeType = "zone"; levelType = "区域"; break;
case 2: nodeType = "station"; levelType = "站点"; break;
case 3: nodeType = "voltage"; levelType = "电压等级"; break;
case 4: nodeType = "bay"; levelType = "间隔"; break;
case 5:
if (hasDevice) {
nodeType = "device";
levelType = "设备";
// 创建设备节点时初始化属性列表
nodeData["properties"] = QVariant::fromValue(QVector<ExtraProperty>());
nodeData["propertyCount"] = 0;
nodeData["deviceId"] = property.component_uuid.toString();
nodeData["deviceName"] = property.component_name;
//nodeData["deviceType"] = property.device_type;
}
break;
}
// 如果是间隔节点第4层也初始化属性列表用于无设备的情况
if (i == 4) {
nodeData["properties"] = QVariant::fromValue(QVector<ExtraProperty>());
nodeData["propertyCount"] = 0;
nodeData["bayName"] = property.bay_name;
nodeData["bayTag"] = property.bay_tag;
}
nodeData["nodeType"] = nodeType;
nodeData["levelType"] = levelType;
newNode->setData(nodeData, Qt::UserRole + 1);
currentNode->appendRow(newNode);
currentNode = newNode;
nodeMap[currentPath] = newNode;
}
}
// 将属性添加到合适的节点
// 如果有设备,添加到设备节点;否则添加到间隔节点
QVariantMap targetNodeData = currentNode->data(Qt::UserRole + 1).toMap();
QVector<ExtraProperty> nodeProperties = targetNodeData["properties"].value<QVector<ExtraProperty>>();
// 检查属性是否已存在
bool propertyExists = false;
for (const auto& existingProp : nodeProperties) {
if (existingProp.code == property.code) {
propertyExists = true;
break;
}
}
if (!propertyExists) {
nodeProperties.append(property);
targetNodeData["properties"] = QVariant::fromValue(nodeProperties);
// 更新属性数量
int propertyCount = targetNodeData["propertyCount"].toInt() + 1;
targetNodeData["propertyCount"] = propertyCount;
// 更新节点显示文本
QString currentText = currentNode->text();
// 移除可能存在的数量后缀
currentText = currentText.replace(QRegularExpression("\\(\\d+\\)$"), "").trimmed();
currentNode->setText(QString("%1 (%2)").arg(currentText).arg(propertyCount));
// 更新工具提示
QString tooltip = QString("%1: %2").arg(targetNodeData["levelType"].toString()).arg(currentText);
if (propertyCount > 0) {
tooltip += QString("\n属性数量: %1").arg(propertyCount);
}
// 添加设备类型信息(如果是设备节点)
if (targetNodeData["nodeType"].toString() == "device") {
tooltip += QString("\n设备类型: %1").arg(targetNodeData["deviceType"].toString());
}
currentNode->setToolTip(tooltip);
// 保存更新后的数据
currentNode->setData(targetNodeData, Qt::UserRole + 1);
}
}
}
// 简化的获取属性列表函数
QVector<ExtraProperty> TopologyView::getPropertiesForNode(QStandardItem* node) {
QVariantMap nodeData = node->data(Qt::UserRole + 1).toMap();
QString nodeType = nodeData.value("nodeType").toString();
if (nodeType == "device" || nodeType == "bay") {
return nodeData["properties"].value<QVector<ExtraProperty>>();
}
return QVector<ExtraProperty>();
}
QString TopologyView::getNodeInfo(QStandardItem* node) {
QVariantMap nodeData = node->data(Qt::UserRole + 1).toMap();
QString nodeType = nodeData.value("nodeType").toString();
QString levelType = nodeData.value("levelType").toString();
QString name = node->text().replace(QRegularExpression("\\(\\d+\\)$"), "").trimmed();
int propertyCount = nodeData.value("propertyCount", 0).toInt();
if (nodeType == "device") {
return QString("%1: %2 (设备类型: %3, 属性数: %4)")
.arg(levelType)
.arg(name)
.arg(nodeData.value("deviceType").toString())
.arg(propertyCount);
} else if (nodeType == "bay") {
return QString("%1: %2 (属性数: %3)")
.arg(levelType)
.arg(name)
.arg(propertyCount);
}
return QString("%1: %2").arg(levelType).arg(name);
}
// 查找或创建电压层级节点
QStandardItem* TopologyView::findOrCreateVoltageLevel(const QString& voltageLevel)
{
if(m_mapVoltageLevels.contains(voltageLevel)){
return m_mapVoltageLevels[voltageLevel];
}
QStandardItem* pVoltageItem = new QStandardItem(voltageLevel);
//pVoltageItem->setCheckable(true);
//pVoltageItem->setCheckState(Qt::Unchecked);
pVoltageItem->setData(-1, Qt::UserRole+1); // 特殊标识,表示电压层级
pVoltageItem->setData(-1, Qt::UserRole+2);
pVoltageItem->setData(QString(), Qt::UserRole+3);
m_mapVoltageLevels[voltageLevel] = pVoltageItem;
_treeModel->appendRow(pVoltageItem);
return pVoltageItem;
}
// 创建间隔节点
QStandardItem* TopologyView::createBayItem(const QString& voltageLevel, const RelationSturctItem& bayInfo)
{
QStandardItem* pBayItem = new QStandardItem(bayInfo.sName);
//pBayItem->setCheckable(true);
//pBayItem->setCheckState(Qt::Unchecked);
pBayItem->setData(bayInfo.nCategory, Qt::UserRole+1);
pBayItem->setData(bayInfo.nEquipType, Qt::UserRole+2);
pBayItem->setData(bayInfo.uid, Qt::UserRole+3);
// 存储到缓存中key 使用"电压层级|间隔名称"确保唯一
QString bayKey = QString("%1|%2").arg(voltageLevel).arg(bayInfo.sName);
m_mapBayItems[bayKey] = pBayItem;
return pBayItem;
}
// 在电压层级下查找间隔节点
QStandardItem* TopologyView::findBayItem(const QString& voltageLevel, const QString& bayName)
{
QString bayKey = QString("%1|%2").arg(voltageLevel).arg(bayName);
// 先从缓存查找
if(m_mapBayItems.contains(bayKey)){
return m_mapBayItems[bayKey];
}
// 在对应电压层级下查找
if(m_mapVoltageLevels.contains(voltageLevel)){
QStandardItem* pVoltageItem = m_mapVoltageLevels[voltageLevel];
for(int i = 0; i < pVoltageItem->rowCount(); ++i){
QStandardItem* pItem = pVoltageItem->child(i);
if(pItem->text() == bayName &&
pItem->data(Qt::UserRole+1).toInt() == 1){
m_mapBayItems[bayKey] = pItem; // 加入缓存
return pItem;
}
}
}
return nullptr;
}
// 创建设备节点
void TopologyView::createDeviceItem(QStandardItem* pParent, const RelationSturctItem& deviceInfo)
{
QStandardItem* pItem = new QStandardItem(deviceInfo.sName);
//pItem->setCheckable(true);
//pItem->setCheckState(Qt::Unchecked);
pItem->setData(deviceInfo.nCategory, Qt::UserRole+1);
pItem->setData(deviceInfo.nEquipType, Qt::UserRole+2);
pItem->setData(deviceInfo.uid, Qt::UserRole+3);
pParent->appendRow(pItem);
}