optimize editor structure

This commit is contained in:
baiYue 2026-05-06 19:48:33 +08:00
parent 4c3151750b
commit 8f152e0b15
31 changed files with 1234 additions and 81 deletions

View File

@ -12,4 +12,31 @@ const int H_DIAGRAM_SPACING = 80;
const int TRANSFORMER_LEVEL = 999; // 层级结构中变压器所处层级
}
/***********布局计算************/
namespace LayoutConstants {
// 容器参数
constexpr double CONTAINER_H_SPACING = 100.0; // 容器水平间距
constexpr double CONTAINER_V_SPACING = 50.0; // 容器垂直基础间距
constexpr double BUS_V_SPACING = 50.0; // 双母线垂直间距
// 设备参数
constexpr double BLOCK_H_SPACING = 20.0; // 设备水平间距
constexpr double BLOCK_V_MARGIN = 20.0; // 设备垂直边距
// 变压器参数
constexpr double TRANSFORMER_START_X = 150.0; // 变压器起始X
constexpr double TRANSFORMER_SPACING = 200.0; // 变压器间距
// 默认尺寸
constexpr double DEFAULT_BLOCK_WIDTH = Constants::EDITOR_ITEM_WIDTH;
constexpr double DEFAULT_BLOCK_HEIGHT = Constants::EDITOR_ITEM_HEIGHT;
// 图层索引
namespace Layer {
constexpr int TOP_BAYS = 0; // 上间隔层
constexpr int BUS1 = 1; // 母线1层
constexpr int BUS2 = 2; // 母线2层
constexpr int BOTTOM_BAYS = 3; // 下间隔层
}
}
#endif

View File

@ -5,5 +5,5 @@ const QMap<AbstractItemType,GraphicsItemType> linkType = {
};
//类型转换
const QMap<int,GraphicsItemType> typeToProGraphic = {
{0,GIT_node},{1,GIT_bus},{3,GIT_itemRect},{4,GIT_ctGroup},{5,GIT_ptGroup},{6,GIT_ES},{7,GIT_FES},{8,GIT_link},{9,GIT_DS},{10,GIT_DTEDS},{11,GIT_PI},{12,GIT_LA},{13,GIT_cableTer},{14,GIT_cableEnd},{15,GIT_2wTransformer},{16,GIT_3wTransformer}
{0,GIT_node},{1,GIT_bus},{3,GIT_itemRect},{4,GIT_ctGroup},{5,GIT_ptGroup},{6,GIT_ES},{7,GIT_FES},{8,GIT_link},{9,GIT_DS},{10,GIT_DTEDS},{11,GIT_PI},{12,GIT_LA},{13,GIT_cableTer},{14,GIT_cableEnd},{15,GIT_2wTransformer},{16,GIT_3wTransformer},{18,GIT_CustomType}
};

View File

@ -78,6 +78,16 @@ set(DIAGRAMCAVAS_HEADER_FILES
include/diagramEditor/diagramEditorTransPreviewDlg.h
include/diagramEditor/diagramEditorPreviewDlg.h
include/diagramEditor/confirmEditorDlg.h
include/diagramEditor/dataModel.h
include/diagramEditor/editItemFactory.h
include/diagramEditor/busItemFactory.h
include/diagramEditor/bayItemFactory.h
include/diagramEditor/transItemFactory.h
include/diagramEditor/hierarchyItemBuilder.h
include/diagramEditor/layoutBuilder.h
include/diagramEditor/transformerBuilder.h
include/diagramEditor/layoutData.h
include/diagramEditor/layoutCalculator.h
include/graphicsDataModel/baseModel.h
include/graphicsDataModel/fixedPortsModel.h
include/graphicsDataModel/diagramEditorModel.h
@ -231,6 +241,14 @@ set(DIAGRAMCAVAS_SOURCE_FILES
source/diagramEditor/diagramEditorTransPreviewDlg.cpp
source/diagramEditor/diagramEditorPreviewDlg.cpp
source/diagramEditor/confirmEditorDlg.cpp
source/diagramEditor/editItemFactory.cpp
source/diagramEditor/busItemFactory.cpp
source/diagramEditor/bayItemFactory.cpp
source/diagramEditor/transItemFactory.cpp
source/diagramEditor/hierarchyItemBuilder.cpp
source/diagramEditor/layoutBuilder.cpp
source/diagramEditor/transformerBuilder.cpp
source/diagramEditor/layoutCalculator.cpp
source/graphicsDataModel/baseModel.cpp
source/graphicsDataModel/fixedPortsModel.cpp
source/graphicsDataModel/diagramEditorModel.cpp

View File

@ -0,0 +1,12 @@
// BayItemFactory.h
#pragma once
#include "editItemFactory.h"
class BayItemFactory : public EditItemFactory {
public:
EditBaseItem* createItem(BlockDataPtr blockData) override;
QGraphicsLinearLayout* createLayerLayout() override;
protected:
void setupItem(EditBaseItem* item, BlockDataPtr blockData) override;
};

View File

@ -0,0 +1,13 @@
// 具体的工厂实现
// BusItemFactory.h
#pragma once
#include "editItemFactory.h"
class BusItemFactory : public EditItemFactory {
public:
EditBaseItem* createItem(BlockDataPtr blockData) override;
QGraphicsLinearLayout* createLayerLayout() override;
protected:
void setupItem(EditBaseItem* item, BlockDataPtr blockData) override;
};

View File

@ -0,0 +1,18 @@
// dataModel.h
#pragma once
#include <QString>
#include <QUuid>
#include <QMap>
#include <QList>
#include "diagramEditor/diagramEditorBaseBlock.h"
// 原始类的前置声明
class DiagramEditorBaseBlock;
class DiagramEditorStructContainer;
class HierarchyItem;
// 类型别名
using BlockDataPtr = DiagramEditorBaseBlock*;
using ContainerDataPtr = DiagramEditorStructContainer*;
using BlockMap = QMap<int, QList<BlockDataPtr>>;
using ContainerStructMap = QMap<int, QList<ContainerDataPtr>>;

View File

@ -2,7 +2,6 @@
#define DIAGRAMEDITORWIZARD_H
#include <QDialog>
//#include "global.h"
#include "tools.h"
#include "common/core_model/diagram.h"

View File

@ -0,0 +1,18 @@
// dataModel.h
#pragma once
#include "diagramEditor/editItems.h"
#include "diagramEditor/dataModel.h"
#include <QGraphicsLinearLayout>
class EditItemFactory {
public:
virtual ~EditItemFactory() = default;
virtual EditBaseItem* createItem(BlockDataPtr blockData) = 0;
virtual QGraphicsLinearLayout* createLayerLayout() = 0;
static EditItemFactory* getFactory(int itemType);
protected:
virtual void setupItem(EditBaseItem* item, BlockDataPtr blockData) = 0;
};

View File

@ -3,7 +3,7 @@
//编辑文本项生成组态图
#include <QWidget>
#include <QPointer>
//#include "global.h"
#include "dataModel.h"
#include "common/core_model/diagram.h"
class EditView;
@ -24,6 +24,15 @@ class DiagramEditorModel;
class DiagramEditorPreviewDlg;
class ConfirmEditorDlg;
class DiagramCavas;
struct HierarchyItem;
class LayoutBuilder;
enum class ConnectionType {
Unknown,
BusBaySameContainer, // 母线-间隔同容器
BusBayDiffContainer, // 母线-间隔跨容器
TransBay // 变压器-间隔
};
class EditPanel : public QWidget
{
@ -63,6 +72,14 @@ private:
void calculateContainerWidth(EditContainerItem*); //根据间隔数量计算容器宽度 todo:区分上下间隔
int getContainerBusType(QMap<int,QList<DiagramEditorBaseBlock*>>); //返回容器中母线类型(单双)
EditBaseItem* getItemByName(const QString&); //根据名称获取指定item
void performCleanup();
void initializeSceneLayout();
void processAllContainerLevels(const ContainerStructMap& containerStruct);
void processNormalContainerLevel(int level, const QList<ContainerDataPtr>& containers,LayoutBuilder& builder);
void processTransformerLevel(const QList<ContainerDataPtr>& containers);
void finalizeConstruction();
void emitTopologySignals();
signals:
void panelDelete(const QString&,int);
protected:
@ -79,6 +96,8 @@ private:
int _maxWidth;
int _maxHeight;
QList<EditRowData*> _lstData;
QList<HierarchyItem> _accumulatedBayItems;
QList<HierarchyItem> _accumulatedDeviceItems;
QMap<int,QMap<int,EditContainerItem*>> _mapStruct;
DiagramEditorModel* _pModel;
DiagramEditorPreviewDlg* _pPreview;

View File

@ -0,0 +1,26 @@
// HierarchyItemBuilder.h
#pragma once
#include "common/core_model/topology.h"
#include "dataModel.h"
class HierarchyItemBuilder {
public:
static HierarchyItemBuilder& instance();
// 创建间隔层级项
HierarchyItem buildBayItem(BlockDataPtr blockData);
// 创建设备层级项
HierarchyItem buildDeviceItem(BlockDataPtr blockData, int deviceType);
// 创建带父间隔的设备项
HierarchyItem buildDeviceWithParent(BlockDataPtr deviceBlock,
BlockDataPtr parentBlock,
int deviceType);
// 根据block类型自动创建对应层级项
HierarchyItem buildAutoFromBlock(BlockDataPtr blockData);
private:
HierarchyItemBuilder() = default;
};

View File

@ -0,0 +1,61 @@
// LayoutBuilder.h
#pragma once
#include <QGraphicsLinearLayout>
#include "editContainerItem.h"
#include "dataModel.h"
#include "common/core_model/topology.h"
class EditPanel;
class EditBaseItem;
class LayoutBuilder {
public:
struct BuildResult {
EditContainerItem* container = nullptr;
QList<HierarchyItem> bayItems;
QList<HierarchyItem> deviceItems;
};
explicit LayoutBuilder(EditPanel* panel);
virtual ~LayoutBuilder() = default;
// 构建一个容器
virtual BuildResult buildContainer(const BlockMap& blockMap);
// 构建行布局
static QGraphicsLinearLayout* createRowLayout();
// 构建垂直布局
static QGraphicsLinearLayout* createVerticalLayout();
// 构建水平布局
static QGraphicsLinearLayout* createHorizontalLayout();
// 添加间隔占位符
static EditBaseItem* createSpacerItem();
// 为垂直布局添加拉伸
static void addStretchToVerticalLayout(QGraphicsLinearLayout* layout);
protected:
EditPanel* m_panel = nullptr;
// 处理一个Block
virtual EditBaseItem* processBlock(BlockDataPtr block,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems);
// 处理一个层的所有Blocks
void processLayer(const QList<BlockDataPtr>& blocks,
QGraphicsLinearLayout* layerLayout,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems);
// 连接信号
void connectSignals(EditBaseItem* item);
void connectContainerSignals(EditContainerItem* container);
protected:
static constexpr int TOTAL_LAYERS = 4; // 总共4层
static constexpr int MIN_CONTAINER_WIDTH = 100; // 最小容器宽度
};

View File

@ -0,0 +1,51 @@
// LayoutCalculator.h
#pragma once
#include "layoutData.h"
#include "common/core_model/constants.h"
class DiagramEditorWizard;
class DiagramEditorBaseBlock;
class DiagramEditorStructContainer;
class FixedLayoutCalculator {
public:
struct LevelLayout {
int level = 0;
double maxUpHeight = 0; // 整行最大上高度
double maxDownHeight = 0; // 整行最大下高度
double startY = 0; // 行起始Y
QList<DiagramEditorStructContainer*> containers;
};
explicit FixedLayoutCalculator(DiagramEditorWizard* wizard);
QMap<DiagramEditorBaseBlock*, QPointF> calculateLayout();
private:
// 第一阶段:计算尺寸
void calculateContainerSizes(LevelLayout& levelLayout);
// 第二阶段:计算位置
void calculatePositions(LevelLayout& levelLayout, double& deltaY, double& lastMaxDownH);
// 计算单个容器的设备位置
void calculateBlockPositionsInContainer(DiagramEditorStructContainer* container,
double startX,
double midUpY,
double midDownY);
// 计算变压器位置
void calculateTransformerPositions(const QList<DiagramEditorStructContainer*>& transformers,
double& deltaY, double& lastMaxDownH);
private:
DiagramEditorWizard* m_wizard = nullptr;
QMap<DiagramEditorBaseBlock*, QPointF> m_blockPositions;
// 全局常量
const double BUS_V_SPACING = 50.0; // 母线1和母线2间距
const double CONTAINER_H_SPACING = 100.0; // 容器水平间距
const double CONTAINER_START_X = 50.0; // 容器起始X
const double TRANSFORMER_START_X = 150.0; // 变压器起始X
const double TRANSFORMER_SPACING = 200.0; // 变压器间距
};

View File

@ -0,0 +1,35 @@
// LayoutData.h
#pragma once
#include <QMap>
#include <QPointF>
#include <QRectF>
class DiagramEditorBaseBlock;
class DiagramEditorStructContainer;
struct ContainerLayout {
double width = 0;
double height = 0;
double maxUpHeight = 0; // 上间隔最大高度
double maxDownHeight = 0; // 下间隔最大高度
double startX = 0; // 容器起始X
double startY = 0; // 容器起始Y
double midUpY = 0; // 母线1中心Y
double midDownY = 0; // 母线2中心Y
QMap<DiagramEditorBaseBlock*, QPointF> blockPositions; // 设备位置
};
struct RowLayout {
int level = 0;
double topY = 0; // 行顶部Y
double height = 0; // 行高度
double width = 0; // 行宽度
QList<ContainerLayout*> containers;
bool isTransformerRow = false;
};
struct LayoutResult {
QMap<int, RowLayout> rows; // 各层级布局
QMap<DiagramEditorBaseBlock*, QPointF> allBlockPositions; // 所有设备位置
QMap<DiagramEditorStructContainer*, ContainerLayout> containerLayouts; // 容器布局
};

View File

@ -0,0 +1,12 @@
// TransItemFactory.h
#pragma once
#include "editItemFactory.h"
class TransItemFactory : public EditItemFactory {
public:
EditBaseItem* createItem(BlockDataPtr blockData) override;
QGraphicsLinearLayout* createLayerLayout() override;
protected:
void setupItem(EditBaseItem* item, BlockDataPtr blockData) override;
};

View File

@ -0,0 +1,26 @@
// TransformerBuilder.h
#pragma once
#include "layoutBuilder.h"
class TransformerBuilder : public LayoutBuilder {
public:
explicit TransformerBuilder(EditPanel* panel);
// 重写容器构建方法
BuildResult buildContainer(const BlockMap& blockMap) override;
// 创建变压器行布局
QGraphicsLinearLayout* createTransformerRowLayout();
// 处理变压器的层级项
HierarchyItem buildTransformerHierarchyItem(BlockDataPtr blockData);
private:
// 处理变压器的特殊逻辑
void processTransformerBlock(BlockDataPtr block,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems);
static constexpr int TRANSFORMER_TYPE = 3;
static constexpr int TRANSFORMER_DEVICE_TYPE = 16;
};

View File

@ -20,7 +20,7 @@ class BaseModel : public QObject
Q_OBJECT
public:
void createTopoTerminalsByItem(GraphicsBaseItem*,ModelFunctionType funType = ModelFunctionType::ProjectModel); //通过图形对象创建port接线点(新建)
QPointF calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item); //计算母线上接线点位置
QPointF calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item,QPointF para = QPointF(0,0)); //计算母线上接线点位置
template<typename TypeLine> void establishConnection(GraphicsBaseItem*,GraphicsBaseItem*,TypeLine*,ModelFunctionType,int nMode=0,int nParam = 0); //在两个item之间建立连接 nMode:0正常1变压器中性点2变压器 nParam附加参数:中性点中表示需连接的位置(012高中低)
double distanceBetweenItems(QGraphicsItem* item1, QGraphicsItem* item2) {
QPointF center1 = item1->mapToScene(item1->boundingRect().center());

View File

@ -5,6 +5,7 @@
#include <QStandardItemModel>
#include "common/core_model/diagram.h"
#include "common/core_model/topology.h"
#include "diagramEditor/layoutData.h"
class GraphicsBaseModelItem;
class DiagramEditorItemProperty;
@ -48,6 +49,7 @@ public:
void calculateBlockPos(); //重新计算block位置
void setItemInBlockPos(); //设置block中的item位置
void refreshConnection(); //刷新连接线
void applyLayoutResult(const LayoutResult& result);
void setCurBayRouteModel(QStandardItemModel* p) {_pCurBayRoute = p;}
QStandardItemModel* getCurBayRouteModel() {return _pCurBayRoute;}

View File

@ -0,0 +1,19 @@
// BusItemFactory.cpp
#include "diagramEditor/bayItemFactory.h"
#include "common/core_model/constants.h"
EditBaseItem* BayItemFactory::createItem(BlockDataPtr blockData) {
auto pBay = new EditBayItem();
setupItem(pBay, blockData);
return pBay;
}
QGraphicsLinearLayout* BayItemFactory::createLayerLayout() {
return new QGraphicsLinearLayout(Qt::Horizontal);
}
void BayItemFactory::setupItem(EditBaseItem* item, BlockDataPtr blockData) {
item->setType(EditorItemType::bay);
item->setBoundingRect(QRectF(0, 0,
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
}

View File

@ -0,0 +1,22 @@
// BusItemFactory.cpp
#include "diagramEditor/busItemFactory.h"
#include "common/core_model/constants.h"
EditBaseItem* BusItemFactory::createItem(BlockDataPtr blockData) {
auto pBus = new EditBusItem();
setupItem(pBus, blockData);
return pBus;
}
QGraphicsLinearLayout* BusItemFactory::createLayerLayout() {
auto layout = new QGraphicsLinearLayout(Qt::Horizontal);
layout->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
layout->setPreferredHeight(10);
return layout;
}
void BusItemFactory::setupItem(EditBaseItem* item, BlockDataPtr blockData) {
item->setType(EditorItemType::bus);
item->setBoundingRect(QRectF(0, 0,
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
}

View File

@ -0,0 +1,24 @@
// EditItemFactory.cpp - 工厂管理器
#include "diagramEditor/editItemFactory.h"
#include "diagramEditor/busItemFactory.h"
#include "diagramEditor/bayItemFactory.h"
#include "diagramEditor/transItemFactory.h"
#include <map>
#include <memory>
EditItemFactory* EditItemFactory::getFactory(int itemType) {
static std::map<int, std::unique_ptr<EditItemFactory>> factories;
// 延迟初始化
if (factories.empty()) {
factories[1] = std::make_unique<BusItemFactory>();
factories[2] = std::make_unique<BayItemFactory>();
factories[3] = std::make_unique<TransItemFactory>();
}
auto it = factories.find(itemType);
if (it != factories.end()) {
return it->second.get();
}
return nullptr;
}

View File

@ -21,9 +21,10 @@
#include "diagramEditor/confirmEditorDlg.h"
#include "projectManager.h"
#include "diagramCavas.h"
//#include "global.h"
#include "common/core_model/constants.h"
#include "basePropertyManager.h"
#include "diagramEditor/transformerBuilder.h"
#include "diagramEditor/layoutBuilder.h"
#include <QDebug>
EditPanel::EditPanel(QWidget *parent)
@ -60,20 +61,18 @@ EditPanel::~EditPanel()
void EditPanel::initByWizardInfo()
{
QList<HierarchyItem> lstBay;
/*QList<HierarchyItem> lstBay;
QList<HierarchyItem> lstItem;
//if(!_lstData.empty() || !_pModel->getPreviewItem().empty()){
_pModel->clearItems();
m_pEditScene->clear();
_lstData.clear();
_mainWidget = new EditMainRect;
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
_widgetLayout->setSpacing(40);
_mainWidget->setLayout(_widgetLayout);
m_pEditScene->addItem(_mainWidget);
_mainWidget->setGeometry(m_pEditScene->sceneRect());
BasePropertyManager::instance().clearEditorData();
//}
_pModel->clearItems();
m_pEditScene->clear();
_lstData.clear();
_mainWidget = new EditMainRect;
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
_widgetLayout->setSpacing(40);
_mainWidget->setLayout(_widgetLayout);
m_pEditScene->addItem(_mainWidget);
_mainWidget->setGeometry(m_pEditScene->sceneRect());
BasePropertyManager::instance().clearEditorData();
auto& mapTotal = _pEditorWizard->getContainerStruct();
for(auto iter = mapTotal.begin();iter != mapTotal.end();++iter){
if(iter.key() == Constants::TRANSFORMER_LEVEL)
@ -145,11 +144,6 @@ void EditPanel::initByWizardInfo()
pBay->setBoundingRect(QRectF(0,0,Constants::EDITOR_ITEM_WIDTH,Constants::EDITOR_ITEM_HEIGHT));
pItem = pBay;
}
/*else if(nType == 3){ //变压器
auto pTrans = new EditTransItem();
pTrans->setType(EditorItemType::Trans);
pItem = pTrans;
}*/
if(pItem){
HierarchyItem bayInfo; //间隔层级
@ -169,7 +163,6 @@ void EditPanel::initByWizardInfo()
}
}
if(mapBlock.value(0).isEmpty()){ //为空则添加间距
//layV->insertStretch(0);
QGraphicsLinearLayout* layH = new QGraphicsLinearLayout(Qt::Horizontal); //container中每一层的布局
layV->insertItem(0,layH);
auto pSpace = new EditBaseItem();
@ -179,7 +172,6 @@ void EditPanel::initByWizardInfo()
}
if(mapBlock.value(3).isEmpty()){ //为空则添加间距
//layV->addStretch();
QGraphicsLinearLayout* layH = new QGraphicsLinearLayout(Qt::Horizontal); //container中每一层的布局
layV->insertItem(3,layH);
auto pSpace = new EditBaseItem();
@ -198,13 +190,8 @@ void EditPanel::initByWizardInfo()
calculateContainerWidth(pContain);
/*int n = getContainerBusType(mapBlock);
if(n == 1){
layoutRowData->setMaximumHeight(210);
}*/
}
_lstData.append(pRow);
//layoutRowData->addStretch();
_widgetLayout->addItem(layoutRowData);
if(iter.key() == 0){ //若设置了变压器,直接插入到第一行下方
@ -303,7 +290,19 @@ void EditPanel::initByWizardInfo()
QTimer::singleShot(300, [&]() { // 1000 毫秒 = 1 秒
qDebug() << "一次性定时器触发!";
initBlockConnection();
});
});*/
// 阶段1: 清理和初始化
performCleanup();
initializeSceneLayout();
// 阶段2: 获取数据
const auto& containerStruct = _pEditorWizard->getContainerStruct();
// 阶段3: 处理所有层级
processAllContainerLevels(containerStruct);
// 阶段4: 完成构建
finalizeConstruction();
}
void EditPanel::initBlockConnection()
@ -324,13 +323,6 @@ void EditPanel::initBlockConnection()
auto pItem1 = getItemByName(item1->getName());
auto pItem2 = getItemByName(item2->getName());
/*QRectF rect1 = pItem1->geometry();
QRectF rect2 = pItem2->geometry();
QPointF center1 = pItem1->mapToScene(rect1.center());
QPointF center2 = pItem2->mapToScene(rect2.center());*/
EditLineItem* pLine = new EditLineItem();
pLine->setName(con.uid.toString());
@ -436,7 +428,6 @@ void EditPanel::initBlockConnection()
}
}
}
}
}
}
@ -673,3 +664,161 @@ void EditPanel::loadBaseSetting(QUuid uid)
_pModel->setWizardInfo(info.context);
}
}
void EditPanel::performCleanup() {
// 清理模型
if (_pModel) {
_pModel->clearItems();
}
// 清理场景
if (m_pEditScene) {
m_pEditScene->clear();
}
// 清理数据
qDeleteAll(_lstData);
_lstData.clear();
_accumulatedBayItems.clear();
_accumulatedDeviceItems.clear();
// 清理主部件
_mainWidget = nullptr;
_widgetLayout = nullptr;
// 清理属性管理器
BasePropertyManager::instance().clearEditorData();
}
void EditPanel::initializeSceneLayout() {
_mainWidget = new EditMainRect;
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
_widgetLayout->setSpacing(40);
_mainWidget->setLayout(_widgetLayout);
m_pEditScene->addItem(_mainWidget);
_mainWidget->setGeometry(m_pEditScene->sceneRect());
}
void EditPanel::processAllContainerLevels(const ContainerStructMap& containerStruct) {
// 普通层级构建器
LayoutBuilder normalBuilder(this);
// 按顺序处理所有层级
auto keys = containerStruct.keys();
std::sort(keys.begin(), keys.end());
for (int level : keys) {
if (level == Constants::TRANSFORMER_LEVEL) {
// 特殊处理变压器层级
processTransformerLevel(containerStruct.value(level));
} else {
// 处理普通层级
processNormalContainerLevel(level, containerStruct.value(level), normalBuilder);
// 如果当前是层级0且存在变压器层级在之后插入变压器
if (level == 0 && containerStruct.contains(Constants::TRANSFORMER_LEVEL)) {
int transformerIndex = keys.indexOf(Constants::TRANSFORMER_LEVEL);
if (transformerIndex > 0) { // 变压器在后面
continue; // 会在遍历到时处理
} else if (transformerIndex < 0) { // 变压器不存在于keys中
processTransformerLevel(containerStruct.value(Constants::TRANSFORMER_LEVEL));
}
}
}
}
}
void EditPanel::processNormalContainerLevel(int level,
const QList<ContainerDataPtr>& containers,
LayoutBuilder& builder) {
if (containers.isEmpty()) return;
// 创建行
auto rowLayout = builder.createRowLayout();
auto rowData = new EditRowData();
rowData->setId(QString::number(level));
// 处理该层级的所有容器
for (auto container : containers) {
if (!container) continue;
const auto& blockMap = container->getBlockMap();
auto result = builder.buildContainer(blockMap);
if (result.container) {
rowLayout->addItem(result.container);
}
// 累积层级项
_accumulatedBayItems.append(result.bayItems);
_accumulatedDeviceItems.append(result.deviceItems);
}
// 保存行数据
_lstData.append(rowData);
_widgetLayout->addItem(rowLayout);
}
void EditPanel::processTransformerLevel(const QList<ContainerDataPtr>& containers) {
if (containers.isEmpty()) return;
// 使用变压器专用构建器
TransformerBuilder transformerBuilder(this);
// 创建变压器行
auto rowLayout = transformerBuilder.createTransformerRowLayout();
auto rowData = new EditRowData();
rowData->setId(QString::number(Constants::TRANSFORMER_LEVEL));
// 处理所有变压器容器
for (auto container : containers) {
if (!container) continue;
const auto& blockMap = container->getBlockMap();
auto result = transformerBuilder.buildContainer(blockMap);
if (result.container) {
rowLayout->addItem(result.container);
}
// 累积变压器层级项
_accumulatedBayItems.append(result.bayItems);
_accumulatedDeviceItems.append(result.deviceItems);
}
// 插入变压器行在层级0之后
_lstData.append(rowData);
// 找到层级0的位置在它之后插入变压器
int insertPosition = 1; // 默认在第一个之后
for (int i = 0; i < _widgetLayout->count(); ++i) {
if (i < _lstData.size() && _lstData[i]->getId() == "0") {
insertPosition = i + 1;
break;
}
}
_widgetLayout->insertItem(insertPosition, rowLayout);
}
void EditPanel::finalizeConstruction() {
// 添加最后的拉伸
_widgetLayout->addStretch();
// 发射拓扑更新信号
emitTopologySignals();
// 延迟初始化连接
QTimer::singleShot(300, this, &EditPanel::initBlockConnection);
}
void EditPanel::emitTopologySignals() {
if (_pModel) {
emit _pModel->updateTopologyItems(_accumulatedBayItems, true, false);
emit _pModel->updateTopologyItems(_accumulatedDeviceItems, false, false);
}
// 清空累积的数据
_accumulatedBayItems.clear();
_accumulatedDeviceItems.clear();
}

View File

@ -0,0 +1,64 @@
// HierarchyItemBuilder.cpp
#include "diagramEditor/hierarchyItemBuilder.h"
HierarchyItemBuilder& HierarchyItemBuilder::instance() {
static HierarchyItemBuilder instance;
return instance;
}
HierarchyItem HierarchyItemBuilder::buildBayItem(BlockDataPtr blockData) {
if (!blockData) return {};
HierarchyItem item;
item.item.nEquipType = 0; // 间隔的设备类型为0
item.item.nCategory = 1; // 类别为1表示间隔
item.item.sName = blockData->getName();
item.item.uid = blockData->getId();
item.item.sVoltageLevel = QString::number(blockData->getVoltage());
return item;
}
HierarchyItem HierarchyItemBuilder::buildDeviceItem(BlockDataPtr blockData, int deviceType) {
if (!blockData) return {};
HierarchyItem item;
item.item.nEquipType = deviceType;
item.item.nCategory = 0; // 类别为0表示设备
item.item.sName = blockData->getName();
item.item.uid = blockData->getId();
item.item.sVoltageLevel = QString::number(blockData->getVoltage());
return item;
}
HierarchyItem HierarchyItemBuilder::buildDeviceWithParent(BlockDataPtr deviceBlock,
BlockDataPtr parentBlock,
int deviceType) {
if (!deviceBlock) return {};
HierarchyItem item = buildDeviceItem(deviceBlock, deviceType);
if (parentBlock) {
item.parent.nEquipType = 0;
item.parent.nCategory = 1;
item.parent.sName = parentBlock->getName();
item.parent.uid = parentBlock->getId();
item.parent.sVoltageLevel = QString::number(parentBlock->getVoltage());
}
return item;
}
HierarchyItem HierarchyItemBuilder::buildAutoFromBlock(BlockDataPtr blockData) {
if (!blockData) return {};
int blockType = blockData->getType();
switch (blockType) {
case 1: // 母线
return buildDeviceWithParent(blockData, blockData, 1);
case 2: // 间隔
return buildBayItem(blockData);
case 3: // 变压器
return buildDeviceWithParent(blockData, blockData, 16);
default:
return {};
}
}

View File

@ -0,0 +1,158 @@
// LayoutBuilder.cpp
#include "diagramEditor/layoutBuilder.h"
#include "diagramEditor/editItemFactory.h"
#include "diagramEditor/hierarchyItemBuilder.h"
#include "common/core_model/constants.h"
#include "diagramEditor/editPanel.h"
#include <QDebug>
LayoutBuilder::LayoutBuilder(EditPanel* panel)
: m_panel(panel) {}
LayoutBuilder::BuildResult LayoutBuilder::buildContainer(const BlockMap& blockMap) {
BuildResult result;
// 1. 创建容器
result.container = new EditContainerItem();
result.container->setMinimumWidth(Constants::EDITOR_ITEM_WIDTH + 40);
result.container->setId(QUuid::createUuid().toString());
// 2. 连接容器信号
connectContainerSignals(result.container);
// 3. 创建垂直布局
auto verticalLayout = createVerticalLayout();
result.container->setLayout(verticalLayout);
// 4. 处理每一层
for (int layerIndex = 0; layerIndex < TOTAL_LAYERS; ++layerIndex) {
auto blocks = blockMap.value(layerIndex);
auto layerLayout = createHorizontalLayout();
verticalLayout->addItem(layerLayout);
if (blocks.isEmpty()) {
// 空层添加占位符
layerLayout->addItem(createSpacerItem());
} else {
// 处理有Blocks的层
processLayer(blocks, layerLayout, result.bayItems, result.deviceItems);
}
}
// 5. 添加拉伸
addStretchToVerticalLayout(verticalLayout);
return result;
}
EditBaseItem* LayoutBuilder::processBlock(BlockDataPtr block,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems) {
if (!block) return nullptr;
// 1. 通过工厂创建Item
auto factory = EditItemFactory::getFactory(block->getType());
if (!factory) {
qWarning() << "No factory found for block type:" << block->getType();
return nullptr;
}
auto editItem = factory->createItem(block);
if (!editItem) {
qWarning() << "Failed to create item for block type:" << block->getType();
return nullptr;
}
// 2. 设置Item属性
editItem->setName(block->getName());
// 注意:这里使用原始指针,不涉及所有权转移
editItem->setBlockData(block);
// 3. 连接信号
connectSignals(editItem);
// 4. 构建层级项
int blockType = block->getType();
switch (blockType) {
case 1: // 母线
bayItems.append(HierarchyItemBuilder::instance().buildBayItem(block));
deviceItems.append(HierarchyItemBuilder::instance().buildDeviceWithParent(block, block, 1));
break;
case 2: // 间隔
bayItems.append(HierarchyItemBuilder::instance().buildBayItem(block));
break;
case 3: // 变压器
// 变压器不创建bayItem但会创建deviceItem
deviceItems.append(HierarchyItemBuilder::instance().buildDeviceWithParent(block, block, 16));
break;
}
return editItem;
}
void LayoutBuilder::processLayer(const QList<BlockDataPtr>& blocks,
QGraphicsLinearLayout* layerLayout,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems) {
if (!layerLayout) return;
for (auto block : blocks) {
auto editItem = processBlock(block, bayItems, deviceItems);
if (editItem) {
layerLayout->addItem(editItem);
}
}
}
void LayoutBuilder::connectSignals(EditBaseItem* item) {
if (!m_panel || !item) return;
QObject::connect(item, &EditBaseItem::itemDbClicked,
m_panel, &EditPanel::onItemDbClicked);
}
void LayoutBuilder::connectContainerSignals(EditContainerItem* container) {
if (!m_panel || !container) return;
QObject::connect(container, &EditContainerItem::containerSizeChange,
m_panel, &EditPanel::onContainerSizeChanged);
}
QGraphicsLinearLayout* LayoutBuilder::createRowLayout() {
auto layout = new QGraphicsLinearLayout(Qt::Horizontal);
layout->setSpacing(20);
layout->setMaximumHeight(300);
return layout;
}
QGraphicsLinearLayout* LayoutBuilder::createVerticalLayout() {
auto layout = new QGraphicsLinearLayout(Qt::Vertical);
layout->setSpacing(10);
layout->setMinimumHeight(260);
return layout;
}
QGraphicsLinearLayout* LayoutBuilder::createHorizontalLayout() {
return new QGraphicsLinearLayout(Qt::Horizontal);
}
EditBaseItem* LayoutBuilder::createSpacerItem() {
auto spacer = new EditBaseItem();
spacer->setType(EditorItemType::None);
spacer->setBoundingRect(QRectF(0, 0,
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
return spacer;
}
void LayoutBuilder::addStretchToVerticalLayout(QGraphicsLinearLayout* layout) {
if (!layout) return;
int count = layout->count();
if (count == 4) {
layout->insertStretch(3);
layout->insertStretch(1);
} else if (count == 2) {
layout->insertStretch(1);
}
}

View File

@ -0,0 +1,265 @@
// LayoutCalculator.cpp
#include "diagramEditor/layoutCalculator.h"
#include "diagramEditor/diagramEditorWizard.h"
#include "diagramEditor/diagramEditorStructContainer.h"
#include "diagramEditor/diagramEditorBaseBlock.h"
#include <QDebug>
FixedLayoutCalculator::FixedLayoutCalculator(DiagramEditorWizard* wizard)
: m_wizard(wizard) {}
QMap<DiagramEditorBaseBlock*, QPointF> FixedLayoutCalculator::calculateLayout() {
m_blockPositions.clear();
if (!m_wizard) {
qWarning() << "FixedLayoutCalculator: Wizard为空";
return m_blockPositions;
}
auto mapTotal = m_wizard->getContainerStruct();
double deltaY = 0;
double lastMaxDownH = 0;
// 按层级顺序处理
for (auto iter = mapTotal.begin(); iter != mapTotal.end(); ++iter) {
int level = iter.key();
if (level == Constants::TRANSFORMER_LEVEL) {
continue; // 变压器特殊处理
}
// 创建层级布局
LevelLayout levelLayout;
levelLayout.level = level;
levelLayout.containers = iter.value();
if (levelLayout.containers.isEmpty()) {
continue;
}
// 第一阶段:计算尺寸
calculateContainerSizes(levelLayout);
// 第二阶段:计算位置
calculatePositions(levelLayout, deltaY, lastMaxDownH);
// 处理变压器在层级0之后
if (level == 0 && mapTotal.contains(Constants::TRANSFORMER_LEVEL)) {
auto transformers = mapTotal.value(Constants::TRANSFORMER_LEVEL);
if (!transformers.isEmpty()) {
calculateTransformerPositions(transformers, deltaY, lastMaxDownH);
}
}
}
return m_blockPositions;
}
void FixedLayoutCalculator::calculateContainerSizes(LevelLayout& levelLayout) {
levelLayout.maxUpHeight = 0;
levelLayout.maxDownHeight = 0;
for (auto container : levelLayout.containers) {
if (!container) continue;
auto mapBlocks = container->getBlockMap();
// 计算上间隔尺寸
auto topBays = mapBlocks.value(0);
double maxUp = 0;
double widthUp = 0;
for (auto block : topBays) {
if (!block) continue;
QRectF rec = block->getRecSize();
maxUp = qMax(maxUp, rec.height());
widthUp += 100 + rec.width();
}
maxUp += Constants::EDITOR_ITEM_HEIGHT;
levelLayout.maxUpHeight = qMax(levelLayout.maxUpHeight, maxUp);
// 计算下间隔尺寸
auto bottomBays = mapBlocks.value(3);
double maxDown = 0;
double widthDown = 0;
for (auto block : bottomBays) {
if (!block) continue;
QRectF rec = block->getRecSize();
maxDown = qMax(maxDown, rec.height());
widthDown += 100 + rec.width();
}
maxDown += Constants::EDITOR_ITEM_HEIGHT;
levelLayout.maxDownHeight = qMax(levelLayout.maxDownHeight, maxDown);
// 计算母线宽度
double busWidth = 0;
auto bus1 = mapBlocks.value(1);
auto bus2 = mapBlocks.value(2);
if (!bus1.isEmpty()) {
busWidth = qMax(busWidth, bus1.first()->getRecSize().width());
}
if (!bus2.isEmpty()) {
busWidth = qMax(busWidth, bus2.first()->getRecSize().width());
}
// 计算容器宽度
double containerWidth = qMax(widthUp, widthDown);
if (containerWidth < busWidth) {
containerWidth = busWidth;
}
// 设置容器尺寸
container->setWidth(containerWidth);
}
// 处理空的情况
if (levelLayout.maxUpHeight == 0) {
levelLayout.maxUpHeight = Constants::EDITOR_ITEM_HEIGHT;
}
if (levelLayout.maxDownHeight == 0) {
levelLayout.maxDownHeight = Constants::EDITOR_ITEM_HEIGHT;
}
}
void FixedLayoutCalculator::calculatePositions(LevelLayout& levelLayout,
double& deltaY, double& lastMaxDownH) {
double startX = CONTAINER_START_X;
bool isFirstContainer = true;
for (auto container : levelLayout.containers) {
if (!container) continue;
// 设置容器高度
container->setMaxUpH(levelLayout.maxUpHeight);
container->setMaxDownH(levelLayout.maxDownHeight);
// 计算垂直位置(每行第一个容器计算一次)
if (isFirstContainer) {
if (levelLayout.level == 0) { // 首行
deltaY = container->getMaxUpH();
} else { // 其他行
deltaY = deltaY + BUS_V_SPACING + lastMaxDownH + container->getMaxUpH();
}
lastMaxDownH = container->getMaxDownH();
isFirstContainer = false;
}
// 设置容器的关键Y坐标
container->setMidUpY(deltaY);
container->setMidDownY(deltaY + BUS_V_SPACING);
container->setStartX(startX);
// 计算容器内设备位置
calculateBlockPositionsInContainer(container, startX, deltaY, deltaY + BUS_V_SPACING);
// 更新水平位置
startX += container->getWidth() + CONTAINER_H_SPACING;
}
}
void FixedLayoutCalculator::calculateBlockPositionsInContainer(DiagramEditorStructContainer* container,
double startX,
double midUpY,
double midDownY) {
if (!container) return;
auto mapBlocks = container->getBlockMap();
double currentX = startX;
for (auto it = mapBlocks.begin(); it != mapBlocks.end(); ++it) {
int layer = it.key();
auto blocks = it.value();
for (auto block : blocks) {
if (!block) continue;
QRectF rec = block->getRecSize();
QPointF center;
int blockType = block->getType();
if (blockType == 1) { // 母线
if (layer == 1) { // 母线1
center = QPointF(startX, midUpY + rec.height() * 0.5);
} else if (layer == 2) { // 母线2
center = QPointF(startX, midDownY - rec.height() * 0.5);
}
} else if (blockType == 2) { // 间隔
if (layer == 0) { // 上间隔
center = QPointF(currentX + rec.width() * 0.5,
midUpY - rec.height() * 0.5 - Constants::EDITOR_ITEM_HEIGHT * 0.5);
} else if (layer == 3) { // 下间隔
center = QPointF(currentX + rec.width() * 0.5,
midDownY + rec.height() * 0.5 + Constants::EDITOR_ITEM_HEIGHT * 0.5);
}
currentX += rec.width();
}
// 变压器不在这里处理
if (!center.isNull()) {
m_blockPositions[block] = center;
block->setSeceneDelta(center);
}
}
}
}
void FixedLayoutCalculator::calculateTransformerPositions(const QList<DiagramEditorStructContainer*>& transformers,
double& deltaY, double& lastMaxDownH) {
if (transformers.isEmpty()) return;
// 计算变压器尺寸
for (auto container : transformers) {
if (!container) continue;
auto mapBlocks = container->getBlockMap();
auto transBlocks = mapBlocks.value(1); // 变压器在layer 1
for (auto block : transBlocks) {
if (!block) continue;
QRectF rec = block->getRecSize();
container->setWidth(rec.width());
container->setHeight(rec.height());
break; // 只取第一个变压器
}
}
// 计算变压器位置
double startX = TRANSFORMER_START_X;
bool isFirstTransformer = true;
for (auto container : transformers) {
if (!container) continue;
// 计算垂直位置
if (isFirstTransformer) {
deltaY = deltaY + BUS_V_SPACING + lastMaxDownH + container->getHeight();
isFirstTransformer = false;
}
double centerY = deltaY - container->getHeight() * 0.5;
container->setStartY(centerY);
container->setStartX(startX);
// 计算变压器内部设备位置
auto mapBlocks = container->getBlockMap();
for (auto it = mapBlocks.begin(); it != mapBlocks.end(); ++it) {
for (auto block : it.value()) {
if (!block) continue;
QRectF rec = block->getRecSize();
QPointF center(startX + rec.width() * 0.5,
centerY + rec.height() * 0.5);
m_blockPositions[block] = center;
block->setSeceneDelta(center);
}
}
// 更新水平位置
startX += container->getWidth() + TRANSFORMER_SPACING;
}
}

View File

@ -0,0 +1,19 @@
// BusItemFactory.cpp
#include "diagramEditor/transItemFactory.h"
#include "common/core_model/constants.h"
EditBaseItem* TransItemFactory::createItem(BlockDataPtr blockData) {
auto pTrans = new EditTransItem();
setupItem(pTrans, blockData);
return pTrans;
}
QGraphicsLinearLayout* TransItemFactory::createLayerLayout() {
return new QGraphicsLinearLayout(Qt::Horizontal);
}
void TransItemFactory::setupItem(EditBaseItem* item, BlockDataPtr blockData) {
item->setType(EditorItemType::trans);
item->setBoundingRect(QRectF(0, 0,
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_WIDTH));
}

View File

@ -0,0 +1,50 @@
// TransformerBuilder.cpp
#include "diagramEditor/transformerBuilder.h"
#include "diagramEditor/hierarchyItemBuilder.h"
TransformerBuilder::TransformerBuilder(EditPanel* panel)
: LayoutBuilder(panel) {}
LayoutBuilder::BuildResult TransformerBuilder::buildContainer(const BlockMap& blockMap) {
BuildResult result = LayoutBuilder::buildContainer(blockMap);
// 为变压器创建额外的层级项
for (int layerIndex = 0; layerIndex < TOTAL_LAYERS; ++layerIndex) {
auto blocks = blockMap.value(layerIndex);
for (auto &block : blocks) {
if (block && block->getType() == TRANSFORMER_TYPE) {
processTransformerBlock(block, result.bayItems, result.deviceItems);
}
}
}
return result;
}
QGraphicsLinearLayout* TransformerBuilder::createTransformerRowLayout() {
auto layout = createRowLayout();
layout->insertStretch(0);
layout->addStretch();
return layout;
}
HierarchyItem TransformerBuilder::buildTransformerHierarchyItem(BlockDataPtr blockData) {
if (!blockData) return {};
return HierarchyItemBuilder::instance()
.buildDeviceWithParent(blockData, blockData, TRANSFORMER_DEVICE_TYPE);
}
void TransformerBuilder::processTransformerBlock(BlockDataPtr block,
QList<HierarchyItem>& bayItems,
QList<HierarchyItem>& deviceItems) {
if (!block) return;
// 变压器需要bayItem吗根据原始代码变压器会创建bayItem
auto bayItem = HierarchyItemBuilder::instance().buildBayItem(block);
bayItems.append(bayItem);
// 创建变压器的deviceItem
auto deviceItem = buildTransformerHierarchyItem(block);
deviceItems.append(deviceItem);
}

View File

@ -42,34 +42,8 @@ void BaseModel::createTopoTerminalsByItem(GraphicsBaseItem* pItem,ModelFunctionT
}
}
QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item)
QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item,QPointF para)
{
//return QPointF(item->pos().x(),pBus->pos().y());
/*QRectF recBus = pBus->sceneBoundingRect();
QLineF busLine = QLineF(recBus.left(),recBus.y(),recBus.right(),recBus.y());
QPointF p1 = busLine.p1();
QPointF p2 = busLine.p2();
// 计算item的中心点在垂直于线段方向上的投影
QPointF itemCenter = item->pos();// + QPointF(item->boundingRect().width()/2, item->boundingRect().height()/2);
// 计算投影点在线段上的位置
QPointF projection;
if (busLine.length() == 0) { // 如果线段长度为0直接返回端点
projection = p1;
} else {
// 计算投影点
QPointF vec = p2 - p1;
QPointF relPos = itemCenter - p1;
qreal dot = QPointF::dotProduct(relPos, vec) / (busLine.length() * busLine.length());
// 限制投影点在线段范围内
dot = qBound(0.0, dot, 1.0);
projection = p1 + dot * vec;
}
return projection;*/
QRectF recBus = pBus->sceneBoundingRect();
QRectF recItem = item->sceneBoundingRect();
@ -81,16 +55,23 @@ QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem*
QPointF p1 = busLine.p1();
QPointF p2 = busLine.p2();
// 计算item的中心点
QPointF itemCenter = recItem.center();
// 计算投影点在线段上的位置
QPointF projection;
if (busLine.length() == 0) {
projection = p1;
} else {
QPointF vec = p2 - p1;
QPointF relPos = itemCenter - p1;
// 如果para不是(0,0)则使用para点计算投影
// 否则使用item的中心点计算投影
QPointF pointToProject;
if (para != QPointF(0, 0)) {
pointToProject = para;
} else {
pointToProject = recItem.center();
}
QPointF relPos = pointToProject - p1;
qreal dot = QPointF::dotProduct(relPos, vec) / (busLine.length() * busLine.length());
dot = qBound(0.0, dot, 1.0);
projection = p1 + dot * vec;

View File

@ -21,6 +21,7 @@
#include <QMetaMethod>
#include "common/core_model/constants.h"
#include "include/instance/baseTypeManager.h"
#include "diagramEditor/layoutCalculator.h"
int g_nCompoWidth = 50; //元件默认宽度(计算布局使用)
int g_nCompoHeight = 50;
@ -796,7 +797,7 @@ void DiagramEditorModel::generatePreview(bool bVisible)
void DiagramEditorModel::calculateBlockPos()
{
if(_pWizard){
/*if(_pWizard){
double deltaY = 0; //竖直方向每行增量
double lastMaxDownH = 0; //上一行的下部最大高度
auto mapTotal = _pWizard->getContainerStruct();
@ -899,10 +900,10 @@ void DiagramEditorModel::calculateBlockPos()
QPointF center;
if(pBlock->getType() == 1){ //母线
if(it.key() == 1){ //1母
center = QPointF(pStartX/*+recBlock.width()*0.5*/,dMiddleUpY+recBlock.height()*0.5);
center = QPointF(pStartX,dMiddleUpY+recBlock.height()*0.5);
}
else if(it.key() == 2){ //2母
center = QPointF(pStartX/*+recBlock.width()*0.5*/,dMiddleDownY-recBlock.height()*0.5);
center = QPointF(pStartX,dMiddleDownY-recBlock.height()*0.5);
}
}
else if(pBlock->getType() == 2){ //间隔
@ -963,7 +964,22 @@ void DiagramEditorModel::calculateBlockPos()
}
}
}
}*/
if (!_pWizard) {
qWarning() << "calculateBlockPos: Wizard为空";
return;
}
// 使用修正后的布局计算器
FixedLayoutCalculator calculator(_pWizard);
// 计算布局
auto blockPositions = calculator.calculateLayout();
// 可以记录布局结果
//m_blockPositions = blockPositions;
qDebug() << "布局计算完成,处理了" << blockPositions.size() << "个设备";
}
void DiagramEditorModel::setItemInBlockPos()
@ -1058,11 +1074,13 @@ void DiagramEditorModel::refreshConnection()
auto pFromData = pFromItem->getProperty();
auto pToData = pToItem->getProperty();
if(pFromData->type() == 1){ //from是母线
QPointF p = calculateBusPortPos(pFromItem,pToItem);
auto pToPort = pToItem->getPortById(toTerId);
QPointF p = calculateBusPortPos(pFromItem,pToItem,pToPort->scenePos());
pFromItem->movePort(fromTerId,pFromItem->mapFromScene(p));
}
else if(pToData->type() == 1){ //to是母线
QPointF p = calculateBusPortPos(pToItem,pFromItem);
auto pFromPort = pFromItem->getPortById(fromTerId);
QPointF p = calculateBusPortPos(pToItem,pFromItem,pFromPort->scenePos());
pToItem->movePort(toTerId,pToItem->mapFromScene(p));
}
@ -1092,6 +1110,20 @@ void DiagramEditorModel::refreshConnection()
}
}
void DiagramEditorModel::applyLayoutResult(const LayoutResult& result) {
// 应用所有设备位置
for (auto it = result.allBlockPositions.begin(); it != result.allBlockPositions.end(); ++it) {
DiagramEditorBaseBlock* block = it.key();
QPointF position = it.value();
if (block) {
block->setSeceneDelta(position);
}
}
qDebug() << "布局计算完成,共处理" << result.allBlockPositions.size() << "个设备";
}
QStandardItem* DiagramEditorModel::getNameItem(const QString& sName,int nFrom)
{
QStandardItemModel* pModel = nullptr;

View File

@ -647,6 +647,34 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
addPortsToItem_json(P_const,portArr,item);
}
else if(type == GIT_CustomType)
{
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
QByteArray svg;
if(model.modelSetting.mapSvg.isEmpty()){
svg = DataBase::GetInstance()->ModelType()[18].icon;
}
else{
svg = ProjectModelManager::instance().getData()[sMeta][sProModel].modelSetting.mapUsedSvg["customType"];
}
if(width == 0 && height == 0){
dX = 40;
dY = 40;
}
else{
dX = width;
dY = height;
}
auto pCustom = new ElectricSvgItem(QRect(-dX*0.5, -dY*0.5, dX, dY));
pCustom->setItemType(GIT_CustomType);
pCustom->loadSvg(svg);
item = pCustom;
QJsonArray portArr = pro->context()["port"].toArray();
addPortsToItem_json(P_const,portArr,item);
}
if(item)
{
item->setItemId(id);

View File

@ -25,6 +25,7 @@ class CreateEditor;
class MonitorItemsDlg;
class MonitorPagesDlg;
class QDetailsView;
class BaseDockWidget;
class CMainWindow : public QMainWindow
{
@ -87,6 +88,7 @@ private:
MonitorPagesDlg* m_pMonitorPagesDlg;
QDockWidget* m_pMonitorItemsDock;
QDockWidget* m_pMonitorPagesDock;
BaseDockWidget* m_pPropertyEditorDock;
QDetailsView* m_pPropertiesEditorView;
QAction* _pActMonitor;
};

View File

@ -47,6 +47,7 @@ CMainWindow::CMainWindow(QWidget *parent)
m_pMonitorItemsDock = nullptr;
m_pMonitorPagesDock = nullptr;
m_pPropertiesEditorView = nullptr;
m_pPropertyEditorDock = nullptr;
_pActMonitor = nullptr;
qRegisterMetaType<PropertyStateInfo>("PropertyStateInfo");
@ -137,12 +138,13 @@ void CMainWindow::initializeDockUi()
connect(&ProjectModelManager::instance(),&ProjectModelManager::modelChange,m_pElectricElementsBox,&ElectricElementsBox::onSignal_modelChanged);
m_pPropertiesEditorView = new QDetailsView();
BaseDockWidget* PropertyEditorDock = new BaseDockWidget(QString::fromWCharArray(L"属性面板"),this);
PropertyEditorDock->setWidget(m_pPropertiesEditorView);
PropertyEditorDock->setMinimumSize(350,150);
m_pPropertiesEditorView->setObject(m_pDiagramCavas);
PropertyEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::RightDockWidgetArea,PropertyEditorDock);
m_pPropertyEditorDock = new BaseDockWidget(QString::fromWCharArray(L"属性面板"),this);
m_pPropertyEditorDock->setWidget(m_pPropertiesEditorView);
m_pPropertyEditorDock->setMinimumSize(350,150);
m_pPropertiesEditorView->setObject(new QObject(this));
m_pPropertyEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::RightDockWidgetArea,m_pPropertyEditorDock);
m_pPropertyEditorDock->hide();
connect(m_pDiagramCavas,&DiagramCavas::selectTarget,this,&CMainWindow::onCavasItemSelected);
}
@ -359,6 +361,7 @@ void CMainWindow::onAction_unloadEditor(const QString& str)
void CMainWindow::onCavasItemSelected(QObject* obj)
{
m_pPropertyEditorDock->show();
if(m_pPropertiesEditorView)
m_pPropertiesEditorView->setObject(obj);
}