optimize editor topology algorithm

This commit is contained in:
baiYue 2026-05-11 18:38:15 +08:00
parent 3afdc864d9
commit 9ef08a005e
14 changed files with 549 additions and 307 deletions

View File

@ -153,7 +153,7 @@ struct DiagramEditorRouteInfo //间隔中单条线路信息
struct DiagramEditorBayInfo //组态编辑间隔信息 struct DiagramEditorBayInfo //组态编辑间隔信息
{ {
QString name; //间隔名 QString name; //间隔名
int nLayout; //布局 0纵向1横向 int nLayout = 0; //布局 0纵向1横向
QList<QUuid> lstFrom; //起始 QList<QUuid> lstFrom; //起始
QList<QUuid> lstTo; //结束 QList<QUuid> lstTo; //结束
QMap<QString,DiagramEditorRouteInfo> mapRoute; //线路信息 QMap<QString,DiagramEditorRouteInfo> mapRoute; //线路信息

View File

@ -4,6 +4,8 @@
// layout_engine.h // layout_engine.h
/********editor布局生成核心类**********/ /********editor布局生成核心类**********/
class DiagramEditorModel;
class DiagramLayoutEngine { class DiagramLayoutEngine {
public: public:
struct Context { struct Context {
@ -17,6 +19,9 @@ public:
} }
}; };
explicit DiagramLayoutEngine(DiagramEditorModel* model)
: m_model(model) {}
QRectF executeLayout( QRectF executeLayout(
QMap<QString, DiagramEditorRouteInfo>& routes, QMap<QString, DiagramEditorRouteInfo>& routes,
QMap<QString, DiagramEditorComponentInfo>& components, QMap<QString, DiagramEditorComponentInfo>& components,
@ -41,7 +46,8 @@ private:
Direction branchDir, Direction branchDir,
const LayoutConfig& config, const LayoutConfig& config,
Context& context, Context& context,
bool isOrder); bool isOrder,
int polarity);
// 组件相关 // 组件相关
Direction determineBranchDirection(const DiagramEditorComponentInfo& currentNode, Direction determineBranchDirection(const DiagramEditorComponentInfo& currentNode,
@ -63,4 +69,5 @@ private:
private: private:
int m_compoWidth = 50; int m_compoWidth = 50;
int m_compoHeight = 30; int m_compoHeight = 30;
DiagramEditorModel* m_model = nullptr;
}; };

View File

@ -27,6 +27,6 @@ private:
Direction m_mainDir = Direction::Down; Direction m_mainDir = Direction::Down;
Direction m_subDir = Direction::Right; Direction m_subDir = Direction::Right;
int m_verticalSpacing = 50; // 默认值 int m_verticalSpacing = 30; // 默认值
int m_horizontalSpacing = 50; // 默认值 int m_horizontalSpacing = 30; // 默认值
}; };

View File

@ -14,6 +14,7 @@ public:
double maxUpHeight = 0; // 整行最大上高度 double maxUpHeight = 0; // 整行最大上高度
double maxDownHeight = 0; // 整行最大下高度 double maxDownHeight = 0; // 整行最大下高度
double startY = 0; // 行起始Y double startY = 0; // 行起始Y
QList<DiagramEditorStructContainer*> containers; QList<DiagramEditorStructContainer*> containers;
}; };

View File

@ -30,6 +30,14 @@ public:
return qSqrt(diff.x() * diff.x() + diff.y() * diff.y()); return qSqrt(diff.x() * diff.x() + diff.y() * diff.y());
} }
ItemPort* getClosestUnusedPort(QMap<QString,ItemPort*>,GraphicsBaseItem* item,ModelFunctionType); //返回距离item最近未使用端点 ItemPort* getClosestUnusedPort(QMap<QString,ItemPort*>,GraphicsBaseItem* item,ModelFunctionType); //返回距离item最近未使用端点
protected:
ItemPort* selectBusOrNodePort(GraphicsBaseItem* pBusOrNode,GraphicsBaseItem* pOther,ModelFunctionType nType); //母线 / 节点端口选择
ItemPort* selectDevicePortByMode(GraphicsBaseItem* pDevice,GraphicsBaseItem* pPeer,int nMode,int nParam,ModelFunctionType nType); //设备端口选择(支持 nMode / nParam
void selectNormalDevicePort(GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,int nMode,int nParam,ModelFunctionType nType,ItemPort*& pSrcPort,ItemPort*& pDestPort);//普通设备 ↔ 设备(含变压器)
void selectTransformerPort(GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,int nMode,int nParam,ItemPort*& pSrcPort,ItemPort*& pDestPort);//变压器端口选择
void selectBusToBusPorts(GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,ModelFunctionType nType,ItemPort*& pSrcPort,ItemPort*& pDestPort);//母线 ↔ 母线 / 节点 ↔ 节点
template<typename TypeLine>
void bindLineAndTopology(ItemPort* pSrcPort,ItemPort* pDestPort,TypeLine* pItem,GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,ModelFunctionType nType);//绑定连线 + 拓扑
}; };

View File

@ -65,7 +65,7 @@ public:
QStandardItem* getNameItem(const QString&,int nFrom = 0); //获取返回当前设备模型中的name项 nFrom,0间隔1变压器 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变压器 void generateItemByModel(QStandardItemModel* pModel,DiagramEditorBaseBlock* pBlock,int nFrom = 0,QPoint delta = QPoint(0,0)); //0间隔1变压器
QList<DiagramEditorComponentInfo> generateItemByInfo(QMap<QString,DiagramEditorRouteInfo> mapRoute,QMap<QString,DiagramEditorComponentInfo> mapCompo,QPointF delta = QPointF(0,0),DiagramEditorBaseBlock* pParent = nullptr); //根据data生成item parent:生成的对象添加到parent下(非拓扑计算) QList<DiagramEditorComponentInfo> generateItemByInfo(QMap<QString,DiagramEditorRouteInfo>& mapRoute,QMap<QString,DiagramEditorComponentInfo>& mapCompo,QPointF delta = QPointF(0,0),DiagramEditorBaseBlock* pParent = nullptr); //根据data生成item parent:生成的对象添加到parent下(非拓扑计算)
QMultiMap<int,QUuid> generateOutConnection(QList<DiagramEditorComponentInfo>,QList<HierarchyItem>&,int nTypeTransCon,int nPos = 0,DiagramEditorBaseBlock* pParent = nullptr); //生成外部连接手动bind的连接relation:层级关系引用 nTypeTransCon变压器连线类型,1中性点连接2外部连接,nPos中性点连接时的位置 QMultiMap<int,QUuid> generateOutConnection(QList<DiagramEditorComponentInfo>,QList<HierarchyItem>&,int nTypeTransCon,int nPos = 0,DiagramEditorBaseBlock* pParent = nullptr); //生成外部连接手动bind的连接relation:层级关系引用 nTypeTransCon变压器连线类型,1中性点连接2外部连接,nPos中性点连接时的位置
QRectF updateTarget(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,int nLayout,int nSource,bool saveToModel = true); //更新位置 nLayout主次朝向:8421,8421 上下左右,上下左右 nSource:0间隔1变压器 regenerate重新生成标志 saveToModel:生成到模型或map QRectF updateTarget(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,int nLayout,int nSource,bool saveToModel = true); //更新位置 nLayout主次朝向:8421,8421 上下左右,上下左右 nSource:0间隔1变压器 regenerate重新生成标志 saveToModel:生成到模型或map
void clearCompoDir(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,int nSource); //清空component中的dir(updateTarget前调用) void clearCompoDir(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,int nSource); //清空component中的dir(updateTarget前调用)

View File

@ -224,13 +224,13 @@ void DiagramEditorBayDetailAddDlg::updateBindLst()
QStandardItem* item = nullptr; QStandardItem* item = nullptr;
if(con.nPara == 0){ if(con.nPara == 0){
item = new QStandardItem("高压接线端子"); item = new QStandardItem("高压线圈接线点");
} }
else if(con.nPara == 1){ else if(con.nPara == 1){
item = new QStandardItem("中压接线端子"); item = new QStandardItem("中压线圈接线点");
} }
else if(con.nPara == 2){ else if(con.nPara == 2){
item = new QStandardItem("低压接线端子"); item = new QStandardItem("低压线圈接线点");
} }
if(item){ if(item){
item->setData(conOp.nType, Qt::UserRole+1); item->setData(conOp.nType, Qt::UserRole+1);

View File

@ -83,7 +83,7 @@ void DiagramEditorBayDetailSettingDlg::refreshModel()
QString sCategory; QString sCategory;
QString sType; QString sType;
if(info.nCategory == 0){ if(info.nCategory == 0){
sCategory = "设备"; sCategory = "电气设备";
sType = BaseTypeManager::getInstance()->getNameById(info.nType); sType = BaseTypeManager::getInstance()->getNameById(info.nType);
} }
else if(info.nCategory == 1){ else if(info.nCategory == 1){
@ -119,11 +119,17 @@ void DiagramEditorBayDetailSettingDlg::refreshModel()
_routeModel->setColumnCount(2); _routeModel->setColumnCount(2);
_routeModel->setHorizontalHeaderLabels({"线路名", "包含设备"}); _routeModel->setHorizontalHeaderLabels({"线路名", "包含设备"});
auto info = _curOperateObj->getBayInfo(); auto info = _curOperateObj->getBayInfo();
if(info.nLayout == 0) //纵向
ui->cb_layout->setCurrentIndex(0);
else
ui->cb_layout->setCurrentIndex(1);
setBayInfo(info); setBayInfo(info);
auto mapRoute = info.mapRoute; //更新路径数据到本界面 auto mapRoute = info.mapRoute; //更新路径数据到本界面
for(auto& route:mapRoute){ for(auto& route:mapRoute){
QString sRoute = route.sRouteName; QString sRoute = route.sRouteName;
if(sRoute.isEmpty())
continue;
QStringList lstComp; QStringList lstComp;
for(auto& comp:route.lstCompo){ for(auto& comp:route.lstCompo){
lstComp.append(comp.sName); lstComp.append(comp.sName);
@ -168,7 +174,7 @@ void DiagramEditorBayDetailSettingDlg::onOkClicked()
//将ui设置的参数更新到对应block //将ui设置的参数更新到对应block
if(_curOperateObj){ if(_curOperateObj){
QMap<QString,DiagramEditorComponentInfo> mapComponents; /*QMap<QString,DiagramEditorComponentInfo> mapComponents;
int nRowCount = _compoModel->rowCount(); int nRowCount = _compoModel->rowCount();
for(int i = 0;i < nRowCount;++i){ for(int i = 0;i < nRowCount;++i){
QStandardItem *itemCate = _compoModel->item(i, 0); QStandardItem *itemCate = _compoModel->item(i, 0);
@ -219,7 +225,74 @@ void DiagramEditorBayDetailSettingDlg::onOkClicked()
QRectF recBounding = getModel()->updateTarget(_curBayInfo.mapRoute,_curBayInfo.mapComponent,nDir,0,false); QRectF recBounding = getModel()->updateTarget(_curBayInfo.mapRoute,_curBayInfo.mapComponent,nDir,0,false);
if(_curOperateObj->getRecSize().isEmpty()) if(_curOperateObj->getRecSize().isEmpty())
_curOperateObj->setRecSize(recBounding); _curOperateObj->setRecSize(recBounding);
_curOperateObj->setBayInfo(_curBayInfo); _curOperateObj->setBayInfo(_curBayInfo);*/
QMap<QString, DiagramEditorComponentInfo> tempComponents;
int nRowCount = _compoModel->rowCount();
for (int i = 0; i < nRowCount; ++i) {
QStandardItem *itemCate = _compoModel->item(i, 0);
QStandardItem *itemName = _compoModel->item(i, 1);
QStandardItem *itemType = _compoModel->item(i, 2);
QStandardItem *itemBind = _compoModel->item(i, 3);
QStandardItem *itemRoute = _compoModel->item(i, 4);
DiagramEditorComponentInfo info;
// ✅ 必须恢复的字段(原代码中有)
int nDir = itemName->data(Qt::UserRole+1).toInt();
QPoint deltaPos = itemName->data(Qt::UserRole+2).toPoint();
int nVal = itemName->data(Qt::UserRole+4).toInt();
int nRotate = itemName->data(Qt::UserRole+5).toInt();
info.sName = itemName->text();
info.uid = itemName->data(Qt::UserRole+3).toUuid();
if(itemCate->text() == "电气设备"){
info.nCategory = 0;
}
else if(itemCate->text() == "连接关系"){
info.nCategory = 1;
}
info.nType = itemType->data().toInt();
info.sBindObj = itemBind->text();
info.nBindType = itemBind->data().toInt();
info.nBindPara = itemBind->data(Qt::UserRole+2).toInt();
info.sBindParent = itemBind->data(Qt::UserRole+3).toString();
info.sUsedRoute = itemRoute->text().split(",");
// ✅ 关键修复:恢复被丢弃的状态
info.nUsedDirection = nDir;
info.deltaPos = deltaPos;
info.nFlag = nVal;
info.nRotate = nRotate;
tempComponents.insert(info.sName, info);
}
// ✅ 2. 设置布局参数
int nLayout = ui->cb_layout->currentData().toInt();
_curBayInfo.nLayout = nLayout;
_curBayInfo.mapComponent = tempComponents; // ✅ 仅存非布局数据
// ✅ 3. 执行布局(唯一正确时机)
int nDir = (nLayout == 0) ? 41 : 14;
getModel()->clearCompoDir(
_curBayInfo.mapRoute,
_curBayInfo.mapComponent,
0);
QRectF recBounding =
getModel()->updateTarget(
_curBayInfo.mapRoute,
_curBayInfo.mapComponent,
nDir,
0,
false); // ✅ 结果写回 mapComponent
// ✅ 4. 保存“已经算好的正确数据”
if (_curOperateObj->getRecSize().isEmpty())
_curOperateObj->setRecSize(recBounding);
_curOperateObj->setBayInfo(_curBayInfo); // ✅ 此时 mapComponent 是正确的
TopologyManager::instance().clearGlobalBlockData(_curOperateObj->getName()); TopologyManager::instance().clearGlobalBlockData(_curOperateObj->getName());
TopologyManager::instance().moveTempBlockData(); TopologyManager::instance().moveTempBlockData();

View File

@ -1,5 +1,6 @@
#include "diagramEditor/editorDiagramLayoutEngine.h" #include "diagramEditor/editorDiagramLayoutEngine.h"
#include "diagramEditor/editorDirectionManager.h" #include "diagramEditor/editorDirectionManager.h"
#include "graphicsDataModel/diagramEditorModel.h"
// 主入口函数 // 主入口函数
QRectF DiagramLayoutEngine::executeLayout( QRectF DiagramLayoutEngine::executeLayout(
@ -8,45 +9,41 @@ QRectF DiagramLayoutEngine::executeLayout(
const LayoutConfig& config, const LayoutConfig& config,
Context& context) { Context& context) {
// 1. 初始化上下文
context.initComponentsCache(components); context.initComponentsCache(components);
context.itemCache.clear(); context.itemCache.clear();
// 2. 查找主线
QString mainRouteName = findMainRoute(routes); QString mainRouteName = findMainRoute(routes);
if (mainRouteName.isEmpty()) { if (mainRouteName.isEmpty()) {
qWarning() << "No main route found"; qWarning() << "No main route found";
return QRectF(); return QRectF();
} }
// 3. 布局主线 // 1. 布局主线
if (routes.contains(mainRouteName)) { layoutMainRoute(routes[mainRouteName], config, context);
layoutMainRoute(routes[mainRouteName], config, context);
}
// 4. 布局所有支线 // 2. 布局所有支线(✅ 此时方向数据必须是最新的)
for (auto it = routes.begin(); it != routes.end(); ++it) { for (auto it = routes.begin(); it != routes.end(); ++it) {
if (it->sRouteName == mainRouteName) continue; if (it->sRouteName == mainRouteName) continue;
layoutBranchRoute(*it, config, context); layoutBranchRoute(*it, config, context);
} }
// 5. 更新组件映射 // ✅ 3. 所有布局完成之后,才更新 components
if (!context.saveToModel) { if (!context.saveToModel) {
for (auto& route : routes) { for(auto& compo:components){ //从compo缓存中读取计算过的数据
for (auto& compo : route.lstCompo) { auto mapCatch = context.componentsCache;
components[compo.sName] = compo; compo.nUsedDirection = mapCatch[compo.sName].nUsedDirection;
} compo.nRotate = mapCatch[compo.sName].nRotate;
compo.deltaPos = mapCatch[compo.sName].deltaPos;
} }
} }
// 6. 计算边界矩形 // 4. 计算边界
if (!context.saveToModel) { if (!context.saveToModel) {
return calculateBoundingRect(components); return calculateBoundingRect(components);
} }
return QRectF(); // saveToModel 时由场景计算边界 return QRectF();
} }
// 查找主线 // 查找主线
QString DiagramLayoutEngine::findMainRoute( QString DiagramLayoutEngine::findMainRoute(
const QMap<QString, DiagramEditorRouteInfo>& routes) { const QMap<QString, DiagramEditorRouteInfo>& routes) {
@ -137,6 +134,9 @@ void DiagramLayoutEngine::layoutMainRoute(
// 计算旋转角度 // 计算旋转角度
int rotate = DirectionManager::getRotationAngle(mainDir); int rotate = DirectionManager::getRotationAngle(mainDir);
if (!context.saveToModel) {
context.componentsCache[compo.sName] = compo;
}
// 更新组件 // 更新组件
updateComponent(compo, dir, delta, rotate, context); updateComponent(compo, dir, delta, rotate, context);
@ -208,19 +208,36 @@ void DiagramLayoutEngine::layoutBranchRoute(
const LayoutConfig& config, const LayoutConfig& config,
Context& context) { Context& context) {
// 1. 拆分支线
splitBranchRoute(route, context); splitBranchRoute(route, context);
// 2. 布局正序序列
if (route.lstOrder.size() > 1) { if (route.lstOrder.size() > 1) {
layoutBranchSequence(route.lstOrder, config.subDirection(), // ✅ 第一个元件的真实方向,由 determineBranchDirection 决定
config, context, true); Direction startDir =
determineBranchDirection(route.lstOrder[0],
config.subDirection(),
context);
int polarity = 1;
layoutBranchSequence(route.lstOrder,
startDir,
config,
context,
true,
polarity);
} }
// 3. 布局反序序列
if (route.lstReverse.size() > 1) { if (route.lstReverse.size() > 1) {
layoutBranchSequence(route.lstReverse, config.subDirection(), Direction startDir =
config, context, false); determineBranchDirection(route.lstReverse[0],
config.subDirection(),
context);
int polarity = -1;
layoutBranchSequence(route.lstReverse,
startDir,
config,
context,
false,
polarity);
} }
} }
@ -230,59 +247,56 @@ void DiagramLayoutEngine::layoutBranchSequence(
Direction branchDir, Direction branchDir,
const LayoutConfig& config, const LayoutConfig& config,
Context& context, Context& context,
bool isOrder) { bool isOrder,
int polarity) {
if (sequence.size() < 2) return; if (sequence.size() < 2) return;
// 获取基准位置 // ✅ 1. 根据主线方向决定展开轴
QPoint basePos = getComponentPosition(sequence[0].sName, context); bool mainIsVertical =
int index = 1; // 偏移索引从1开始 DirectionManager::isVertical(config.mainDirection());
int polarity = 1; // 方向极性
// 确定极性 // ✅ 2. 间距由主线方向决定
if (branchDir == Direction::Left || branchDir == Direction::Up) { int spacing = mainIsVertical
polarity = -1;
}
// 计算间距
int spacing = DirectionManager::isHorizontal(branchDir)
? config.horizontalSpacing() ? config.horizontalSpacing()
: config.verticalSpacing(); : config.verticalSpacing();
// 布局后续元件
for (int i = 0; i < sequence.size() - 1; ++i) {
DiagramEditorComponentInfo& current = sequence[i];
DiagramEditorComponentInfo& next = sequence[i + 1];
// 确定分支方向 for (int i = 0; i < sequence.size(); ++i) {
Direction dir = determineBranchDirection(current, branchDir, context);
// 计算下一个元件的位置 // ✅ 当前元件作为“起点”
QPoint nextPos = basePos; QPoint basePos = getComponentPosition(sequence[i].sName, context);
int offset = index * polarity * spacing; Direction dir =
determineBranchDirection(sequence[i], branchDir, context);
if (DirectionManager::isHorizontal(dir)) { // ✅ 如果后面还有元件,才计算偏移
nextPos.setX(basePos.x() + offset); if (i + 1 < sequence.size()) {
} else {
nextPos.setY(basePos.y() + offset); DiagramEditorComponentInfo& next = sequence[i + 1];
int offset = (i + 1) * polarity * spacing;
QPoint nextPos = basePos;
if (mainIsVertical) {
// ✅ 只在 X 轴应用偏移Y 轴纹丝不动
nextPos.setX(basePos.x() + offset);
// nextPos.setY(basePos.y()); // ✅ 隐式成立,无需再写
} else {
// ✅ 只在 Y 轴应用偏移X 轴纹丝不动
nextPos.setY(basePos.y() + offset);
// nextPos.setX(basePos.x()); // ✅ 隐式成立,无需再写
}
QPoint deltaPos = nextPos - basePos;
Direction nextConnectionDir =
DirectionManager::getOpposite(dir);
int rotate =
DirectionManager::getRotationAngle(dir);
updateComponent(next, nextConnectionDir,
nextPos, rotate, context);
} }
// 计算相对位置
QPoint deltaPos = nextPos - basePos;
// 下一个元件的连接方向与当前方向相反
Direction nextConnectionDir = DirectionManager::getOpposite(dir);
// 计算旋转角度
int rotate = DirectionManager::getRotationAngle(dir);
// 更新元件
updateComponent(next, nextConnectionDir, deltaPos, rotate, context);
index++;
} }
} }
// 确定支线方向 // 确定支线方向
Direction DiagramLayoutEngine::determineBranchDirection( Direction DiagramLayoutEngine::determineBranchDirection(
const DiagramEditorComponentInfo& currentNode, const DiagramEditorComponentInfo& currentNode,
@ -340,13 +354,24 @@ QPoint DiagramLayoutEngine::getComponentPosition(
return posData.toPoint(); return posData.toPoint();
} }
} }
return QPoint(0, 0);
} else { } else {
// ✅ 核心修复:优先使用 componentsCache
if (context.componentsCache.contains(componentName)) { if (context.componentsCache.contains(componentName)) {
return context.componentsCache[componentName].deltaPos; return context.componentsCache[componentName].deltaPos;
} }
}
return QPoint(0, 0); // ✅ 终极兜底:如果 cache 里也没有,从原始 components 取
QStandardItem* item = getNameItem(componentName, context);
if (item) {
QVariant posData = item->data(Qt::UserRole + 2);
if (posData.isValid() && posData.canConvert<QPoint>()) {
return posData.toPoint(); // ✅ 返回真实的 deltaPos
}
}
return QPoint(0, 0);
}
} }
// 获取组件方向 // 获取组件方向
@ -370,16 +395,10 @@ QStandardItem* DiagramLayoutEngine::getNameItem(
const QString& name, const QString& name,
Context& context) { Context& context) {
QString cacheKey = QString("%1_%2").arg(name).arg(context.sourceId); if (!m_model)
return nullptr;
if (!context.itemCache.contains(cacheKey)) { return m_model->getNameItem(name, context.sourceId);
// 这里应该是具体的模型查找实现
// 为了示例,返回一个临时项
QStandardItem* item = new QStandardItem(name);
context.itemCache[cacheKey] = item;
}
return context.itemCache[cacheKey];
} }
// 更新组件 // 更新组件
@ -398,6 +417,13 @@ void DiagramLayoutEngine::updateComponent(
item->setData(QString::number(newDir)); item->setData(QString::number(newDir));
item->setData(position, Qt::UserRole + 2); item->setData(position, Qt::UserRole + 2);
item->setData(rotate, Qt::UserRole + 5); item->setData(rotate, Qt::UserRole + 5);
//compo.nUsedDirection = DirectionManager::markDirectionOccupied(compo.nUsedDirection, dir);
//compo.deltaPos = position;
//compo.nRotate = rotate;
// 更新缓存
//context.componentsCache[compo.sName] = compo;
} }
} else { } else {
compo.nUsedDirection = DirectionManager::markDirectionOccupied(compo.nUsedDirection, dir); compo.nUsedDirection = DirectionManager::markDirectionOccupied(compo.nUsedDirection, dir);
@ -405,7 +431,9 @@ void DiagramLayoutEngine::updateComponent(
compo.nRotate = rotate; compo.nRotate = rotate;
// 更新缓存 // 更新缓存
context.componentsCache[compo.sName] = compo; context.componentsCache[compo.sName].nUsedDirection = compo.nUsedDirection;
context.componentsCache[compo.sName].deltaPos = compo.deltaPos;
context.componentsCache[compo.sName].nRotate = compo.nRotate;
} }
} }

View File

@ -59,7 +59,7 @@ void FixedLayoutCalculator::calculateContainerSizes(LevelLayout& levelLayout) {
levelLayout.maxUpHeight = 0; levelLayout.maxUpHeight = 0;
levelLayout.maxDownHeight = 0; levelLayout.maxDownHeight = 0;
for (auto container : levelLayout.containers) { for (auto& container : levelLayout.containers) {
if (!container) continue; if (!container) continue;
auto mapBlocks = container->getBlockMap(); auto mapBlocks = container->getBlockMap();
@ -128,7 +128,7 @@ void FixedLayoutCalculator::calculatePositions(LevelLayout& levelLayout,
double startX = CONTAINER_START_X; double startX = CONTAINER_START_X;
bool isFirstContainer = true; bool isFirstContainer = true;
for (auto container : levelLayout.containers) { for (auto& container : levelLayout.containers) {
if (!container) continue; if (!container) continue;
// 设置容器高度 // 设置容器高度

View File

@ -99,7 +99,320 @@ ItemPort* BaseModel::getClosestUnusedPort(QMap<QString,ItemPort*> mapPorts,Graph
return nullptr; return nullptr;
} }
template<typename TypeLine> void BaseModel::establishConnection(GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,TypeLine* pItem,ModelFunctionType nType,int nMode,int nParam) ItemPort* BaseModel::selectBusOrNodePort(
GraphicsBaseItem* pBusOrNode,
GraphicsBaseItem* pOther,
ModelFunctionType nType)
{
ItemPort* pPort = nullptr;
int nTypeSelf = pBusOrNode->getProperty()->type();
if (nTypeSelf == 1) // 母线
{
int index = pBusOrNode->addPort(
p_movable,
pBusOrNode->mapFromScene(
calculateBusPortPos(pBusOrNode, pOther)));
createTopoTerminalsByItem(pBusOrNode, nType);
pPort = pBusOrNode->getPortPtr(index);
}
else // 节点
{
int index = pBusOrNode->addPort(
p_movable, QPoint(0,0));
createTopoTerminalsByItem(pBusOrNode, nType);
pPort = pBusOrNode->getPortPtr(index);
}
return pPort;
}
ItemPort* BaseModel::selectDevicePortByMode(
GraphicsBaseItem* pDevice,
GraphicsBaseItem* pPeer,
int nMode,
int nParam,
ModelFunctionType nType)
{
ItemPort* pPort = nullptr;
QMap<QString, ItemPort*> mapPorts = pDevice->getPorts();
if (nMode == 0)
{
pPort = getClosestUnusedPort(mapPorts, pPeer, nType);
}
else if (nMode == 1) // 中性点
{
for (auto& port : mapPorts)
{
if (port->getType() == T_newTral)
{
int pos = port->portPos();
if ((nParam == 0 && pos == P_top) ||
(nParam == 1 && (pos == P_left || pos == P_right)) ||
(nParam == 2 && pos == P_down))
{
pPort = port;
break;
}
}
}
}
else if (nMode == 2) // 非中性点
{
for (auto& port : mapPorts)
{
if (port->getType() != T_newTral)
{
int pos = port->portPos();
if ((nParam == 0 && pos == P_top) ||
(nParam == 1 && (pos == P_left || pos == P_right)) ||
(nParam == 2 && pos == P_down))
{
pPort = port;
break;
}
}
}
}
return pPort;
}
void BaseModel::selectNormalDevicePort(
GraphicsBaseItem* pSrc,
GraphicsBaseItem* pDest,
int nMode,
int nParam,
ModelFunctionType nType,
ItemPort*& pSrcPort,
ItemPort*& pDestPort)
{
if (nMode == 1 || nMode == 2)
{
selectTransformerPort(pSrc, pDest,
nMode, nParam,
pSrcPort, pDestPort);
}
else
{
QMap<QString, ItemPort*> mapSrc = pSrc->getPorts();
QMap<QString, ItemPort*> mapDest = pDest->getPorts();
for (auto& port : mapSrc)
if (port->getType() == T_lineOut)
pSrcPort = port;
for (auto& port : mapDest)
if (port->getType() == T_lineIn)
pDestPort = port;
}
}
void BaseModel::selectTransformerPort(
GraphicsBaseItem* pSrc,
GraphicsBaseItem* pDest,
int nMode,
int nParam,
ItemPort*& pSrcPort,
ItemPort*& pDestPort)
{
int nTypeSrc = pSrc->getProperty()->type();
int nTypeDest = pDest->getProperty()->type();
QMap<QString, ItemPort*> mapSrc = pSrc->getPorts();
QMap<QString, ItemPort*> mapDest = pDest->getPorts();
// src 是变压器
if (nTypeSrc == 15 || nTypeSrc == 16)
{
for (auto& port : mapSrc)
{
int tpe = port->getType();
int pos = port->portPos();
if (tpe != T_newTral)
{
if ((nParam == 0 && pos == P_top) ||
(nParam == 1 && (pos == P_left || pos == P_right)) ||
(nParam == 2 && pos == P_down))
{
pSrcPort = port;
break;
}
}
}
int transType = pSrcPort ? pSrcPort->getType() : 0;
for (auto& port : mapDest)
{
if (transType == T_lineOut && port->getType() == T_lineIn)
{
pDestPort = port;
break;
}
else if (transType == T_lineIn && port->getType() == T_lineOut)
{
pDestPort = port;
break;
}
}
}
// dest 是变压器
else if (nTypeDest == 15 || nTypeDest == 16)
{
for (auto& port : mapDest)
{
int tpe = port->getType();
int pos = port->portPos();
if (tpe != T_newTral)
{
if ((nParam == 0 && pos == P_top) ||
(nParam == 1 && (pos == P_left || pos == P_right)) ||
(nParam == 2 && pos == P_down))
{
pDestPort = port;
break;
}
}
}
int transType = pDestPort ? pDestPort->getType() : 0;
for (auto& port : mapSrc)
{
if (transType == T_lineOut && port->getType() == T_lineIn)
{
pSrcPort = port;
break;
}
else if (transType == T_lineIn && port->getType() == T_lineOut)
{
pSrcPort = port;
break;
}
}
}
}
void BaseModel::selectBusToBusPorts(
GraphicsBaseItem* pSrc,
GraphicsBaseItem* pDest,
ModelFunctionType nType,
ItemPort*& pSrcPort,
ItemPort*& pDestPort)
{
int idx = pSrc->addPort(
p_movable,
pSrc->mapFromScene(
calculateBusPortPos(pSrc, pDest)));
createTopoTerminalsByItem(pSrc, nType);
pSrcPort = pSrc->getPortPtr(idx);
idx = pDest->addPort(
p_movable,
pDest->mapFromScene(
calculateBusPortPos(pDest, pSrc)));
createTopoTerminalsByItem(pDest, nType);
pDestPort = pDest->getPortPtr(idx);
}
template<typename TypeLine>
void BaseModel::bindLineAndTopology(
ItemPort* pSrcPort,
ItemPort* pDestPort,
TypeLine* pItem,
GraphicsBaseItem* pSrc,
GraphicsBaseItem* pDest,
ModelFunctionType nType)
{
if (!pSrcPort || !pDestPort)
return;
pItem->setStartPoint(pSrcPort->scenePos());
pItem->setEndPoint(pDestPort->scenePos());
pItem->calculatePath();
PowerConnection* pCon =
TopologyManager::instance().createConnection(
pItem->itemId().toString(),
pSrcPort->getId(),
pDestPort->getId(),
pSrc->itemId().toString(),
pDest->itemId().toString(),
nType);
if (pCon)
pCon->setState(DataState::Changed);
pItem->getProperty()->setConnection(
Connection(
pSrc->itemId(),
QUuid(pSrcPort->getId()),
pSrcPort->getType(),
pSrcPort->portPos(),
pDest->itemId(),
QUuid(pDestPort->getId()),
pDestPort->getType(),
pDestPort->portPos()));
}
template<typename TypeLine>
void BaseModel::establishConnection(
GraphicsBaseItem* pSrc,
GraphicsBaseItem* pDest,
TypeLine* pItem,
ModelFunctionType nType,
int nMode,
int nParam)
{
ItemPort* pSrcPort = nullptr;
ItemPort* pDestPort = nullptr;
auto pSrcData = pSrc->getProperty();
auto pDestData = pDest->getProperty();
int nTypeSrc = 0;
int nTypeDest = 0;
if(pSrcData)
nTypeSrc = pSrcData->type();
if(pDestData)
nTypeDest = pDestData->type();
// ===== 场景 1源是母线或节点 =====
if ((nTypeSrc == 1 || nTypeSrc == 0) &&
(nTypeDest != 1 && nTypeDest != 0))
{
pSrcPort = selectBusOrNodePort(pSrc, pDest, nType);
pDestPort = selectDevicePortByMode(pDest, pSrc, nMode, nParam, nType);
}
// ===== 场景 2目标是母线或节点 =====
else if ((nTypeDest == 1 || nTypeDest == 0) &&
(nTypeSrc != 1 && nTypeSrc != 0))
{
pDestPort = selectBusOrNodePort(pDest, pSrc, nType);
pSrcPort = selectDevicePortByMode(pSrc, pDest, nMode, nParam, nType);
}
// ===== 场景 3两端都是母线或节点 =====
else if ((nTypeSrc == 1 || nTypeSrc == 0) &&
(nTypeDest == 1 || nTypeDest == 0))
{
selectBusToBusPorts(pSrc, pDest, nType,
pSrcPort, pDestPort);
}
// ===== 场景 4普通设备 ↔ 设备 =====
else
{
selectNormalDevicePort(pSrc, pDest,
nMode, nParam, nType,
pSrcPort, pDestPort);
}
// ===== 绑定 =====
bindLineAndTopology(pSrcPort, pDestPort,
pItem, pSrc, pDest, nType);
}
/*template<typename TypeLine> void BaseModel::establishConnection(GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,TypeLine* pItem,ModelFunctionType nType,int nMode,int nParam)
{ {
ItemPort* pSrcPort = nullptr; ItemPort* pSrcPort = nullptr;
ItemPort* pDestPort = nullptr; ItemPort* pDestPort = nullptr;
@ -457,6 +770,6 @@ template<typename TypeLine> void BaseModel::establishConnection(GraphicsBaseItem
pCon->setState(DataState::Changed); pCon->setState(DataState::Changed);
pItem->getProperty()->setConnection(Connection(pSrc->itemId(),QUuid(pSrcPort->getId()),pSrcPort->getType(),pSrcPort->portPos(),pDest->itemId(),QUuid(pDestPort->getId()),pDestPort->getType(),pDestPort->portPos())); pItem->getProperty()->setConnection(Connection(pSrc->itemId(),QUuid(pSrcPort->getId()),pSrcPort->getType(),pSrcPort->portPos(),pDest->itemId(),QUuid(pDestPort->getId()),pDestPort->getType(),pDestPort->portPos()));
} }
} }*/
template void BaseModel::establishConnection<ElectricBaseModelLineItem>(GraphicsBaseItem*,GraphicsBaseItem*,ElectricBaseModelLineItem*,ModelFunctionType,int,int); template void BaseModel::establishConnection<ElectricBaseModelLineItem>(GraphicsBaseItem*,GraphicsBaseItem*,ElectricBaseModelLineItem*,ModelFunctionType,int,int);

View File

@ -22,6 +22,7 @@
#include "common/core_model/constants.h" #include "common/core_model/constants.h"
#include "include/instance/baseTypeManager.h" #include "include/instance/baseTypeManager.h"
#include "diagramEditor/layoutCalculator.h" #include "diagramEditor/layoutCalculator.h"
#include "diagramEditor/editorDiagramLayoutEngine.h"
int g_nCompoWidth = 50; //元件默认宽度(计算布局使用) int g_nCompoWidth = 50; //元件默认宽度(计算布局使用)
int g_nCompoHeight = 50; int g_nCompoHeight = 50;
@ -797,174 +798,6 @@ void DiagramEditorModel::generatePreview(bool bVisible)
void DiagramEditorModel::calculateBlockPos() void DiagramEditorModel::calculateBlockPos()
{ {
/*if(_pWizard){
double deltaY = 0; //竖直方向每行增量
double lastMaxDownH = 0; //上一行的下部最大高度
auto mapTotal = _pWizard->getContainerStruct();
for(auto iter = mapTotal.begin();iter != mapTotal.end();++iter){
if(iter.key() == Constants::TRANSFORMER_LEVEL)
continue;
double dMaxUp = 0; //计算最大上方空间
double dMaxDown = 0; //计算最大下方空间
for(auto &pCon:iter.value()){ //首次循环遍历每行container,计算最大上空间高度,最大下空间高度,容器宽度
auto mapBlocks = pCon->getBlockMap();
auto lstBlockUp = mapBlocks.value(0);
auto lstBus1 = mapBlocks.value(1); //1母
auto lstBus2 = mapBlocks.value(2); //2母
auto lstBlockDown = mapBlocks.value(3);
double dConWidth = 0;
double dWidthUp = 0;
for(auto pBlock:lstBlockUp){
QRectF rec = pBlock->getRecSize();
double dHeight = rec.height();
double dWidth = rec.width();
if(dMaxUp < dHeight)
dMaxUp = dHeight;
dWidthUp += g_nHorizontalBlockSpacing+dWidth;
}
dMaxUp += Constants::EDITOR_ITEM_HEIGHT;
double dWidthDown = 0;
for(auto pBlock:lstBlockDown){
QRectF rec = pBlock->getRecSize();
double dHeight = rec.height();
double dWidth = rec.width();
if(dMaxDown < dHeight)
dMaxDown = dHeight;
dWidthDown = g_nHorizontalBlockSpacing+dWidth;
}
dMaxDown += Constants::EDITOR_ITEM_HEIGHT;
int nBusLen = 0;
if(!lstBus1.empty()){
nBusLen = lstBus1.first()->getRecSize().width();
}
if(!lstBus2.empty()){
int nLen = lstBus2.first()->getRecSize().width();
if(nBusLen < nLen)
nBusLen = nLen;
}
dConWidth = dWidthUp > dWidthDown ? dWidthUp : dWidthDown;
if(dConWidth < nBusLen)
dConWidth = nBusLen;
pCon->setWidth(dConWidth);
}
if(dMaxUp == 0){
dMaxUp = Constants::EDITOR_ITEM_HEIGHT;
}
if(dMaxDown == 0){
dMaxDown = Constants::EDITOR_ITEM_HEIGHT;
}
double dDeltaX = 50; //每行横向偏移
for(auto &pCon:iter.value()){ //第二次循环赋值,计算位置(首先确定母线位置)
pCon->setMaxUpH(dMaxUp);
pCon->setMaxDownH(dMaxDown);
if(iter.value().first() == pCon){ //每行只进行一次y位移
if(iter == mapTotal.begin()){ //首行 deltaY = 首行dMaxUpH
deltaY = pCon->getMaxUpH();
}
else if(iter == std::next(mapTotal.begin())){ //第二行
if(!mapTotal.value(Constants::TRANSFORMER_LEVEL).empty()){ //有变压器
deltaY = deltaY + pCon->getMaxUpH();
}
else
deltaY = deltaY + 50 + lastMaxDownH + pCon->getMaxUpH();
}
else //其他行 deltaY = deltaY+母线高度+上行dMaxDownH+本行dMaxUpH
{
deltaY = deltaY + 50 + lastMaxDownH + pCon->getMaxUpH();
}
lastMaxDownH = pCon->getMaxDownH();
}
pCon->setMidUpY(deltaY);
pCon->setMidDownY(deltaY+50);
pCon->setStartX(dDeltaX);
dDeltaX += pCon->getWidth()+100;
//计算container中block中心点的位置
auto mapBlocks = pCon->getBlockMap();
for(auto it = mapBlocks.begin();it != mapBlocks.end();++it){
double pStartX = pCon->getStartX(); //容器起始x
double dMiddleUpY = pCon->getMidUpY(); //获取1母上边y
double dMiddleDownY = pCon->getMidDownY(); //获取2母下边y
double deltaX = pStartX;
for(auto pBlock:it.value()){
QRectF recBlock = pBlock->getRecSize();
QPointF center;
if(pBlock->getType() == 1){ //母线
if(it.key() == 1){ //1母
center = QPointF(pStartX,dMiddleUpY+recBlock.height()*0.5);
}
else if(it.key() == 2){ //2母
center = QPointF(pStartX,dMiddleDownY-recBlock.height()*0.5);
}
}
else if(pBlock->getType() == 2){ //间隔
if(it.key() == 0){ //容器最上层
center = QPointF(deltaX+recBlock.width()*0.5,dMiddleUpY-recBlock.height()*0.5-Constants::EDITOR_ITEM_HEIGHT*0.5);
}
else if(it.key() == 3){ //容器最下层
center = QPointF(deltaX+recBlock.width()*0.5,dMiddleDownY+recBlock.height()*0.5+Constants::EDITOR_ITEM_HEIGHT*0.5);
}
deltaX += recBlock.width();
}
else if(pBlock->getType() == 3){ //变压器
}
if(!center.isNull())
pBlock->setSeceneDelta(center);
//qDebug()<<pBlock->getName()<<":"<<center<<"-"<<recBlock;
}
}
}
dDeltaX = 150; //首个变压器位置
if(iter.key() == 0){ //若设置了变压器,直接插入到第一行下方
if(!mapTotal.value(Constants::TRANSFORMER_LEVEL).empty()){
auto lstCon = mapTotal.value(Constants::TRANSFORMER_LEVEL);
for(auto &pCon:lstCon){ //首次计算变压器大小
auto mapBlocks = pCon->getBlockMap();
auto lstBlock = mapBlocks.value(1);
for(auto &pb:lstBlock){
QRectF rec = pb->getRecSize();
pCon->setWidth(rec.width());
pCon->setHeight(rec.height());
}
}
for(auto &pCon:lstCon){ //计算位置
if(pCon == lstCon.first()){
//只在每行第一次改变deltaY
deltaY = deltaY + 50 + lastMaxDownH + pCon->getHeight();
}
double dHeight = pCon->getHeight();
double dWidth = pCon->getWidth();
pCon->setStartY(deltaY-dHeight*0.5);
pCon->setStartX(dDeltaX);
dDeltaX += dWidth+200;
auto mapBlocks = pCon->getBlockMap();
for(auto it = mapBlocks.begin();it != mapBlocks.end();++it){
for(auto pBlock:it.value()){
QRectF recBlock = pBlock->getRecSize();
QPointF center = QPointF(pCon->getStartX()+recBlock.width()*0.5,pCon->getStartY()+recBlock.height()*0.5);
pBlock->setSeceneDelta(center);
qDebug()<<pBlock->getName()<<":"<<center<<"-"<<recBlock;
}
}
}
}
}
}
}*/
if (!_pWizard) { if (!_pWizard) {
qWarning() << "calculateBlockPos: Wizard为空"; qWarning() << "calculateBlockPos: Wizard为空";
return; return;
@ -1213,7 +1046,7 @@ void DiagramEditorModel::generateItemByModel(QStandardItemModel* pModel,DiagramE
} }
} }
QList<DiagramEditorComponentInfo> DiagramEditorModel::generateItemByInfo(QMap<QString,DiagramEditorRouteInfo> mapRoute,QMap<QString,DiagramEditorComponentInfo> mapCompo,QPointF delta,DiagramEditorBaseBlock* pParent) QList<DiagramEditorComponentInfo> DiagramEditorModel::generateItemByInfo(QMap<QString,DiagramEditorRouteInfo>& mapRoute,QMap<QString,DiagramEditorComponentInfo>& mapCompo,QPointF delta,DiagramEditorBaseBlock* pParent)
{ {
QList<DiagramEditorComponentInfo> lstBind; //连接外部对象的component QList<DiagramEditorComponentInfo> lstBind; //连接外部对象的component
QString sMain; QString sMain;
@ -1503,21 +1336,33 @@ void DiagramEditorModel::clearCompoDir(QMap<QString,DiagramEditorRouteInfo>& dat
compoInfo.nRotate = 0; compoInfo.nRotate = 0;
} }
} }
/*for(auto &routeInfo:data){
routeInfo.lstOrder.clear();
routeInfo.lstReverse.clear();
for(auto &compo:routeInfo.lstCompo){
compo.nUsedDirection = 0;
}
}
for(auto &compoInfo:compos){
compoInfo.nUsedDirection = 0;
compoInfo.nRotate = 0;
}*/
} }
QRectF DiagramEditorModel::updateTarget(QMap<QString,DiagramEditorRouteInfo>& data,QMap<QString,DiagramEditorComponentInfo>& compos,int nLayout,int nSource,bool saveToModel) QRectF DiagramEditorModel::updateTarget(
QMap<QString, DiagramEditorRouteInfo>& data,
QMap<QString, DiagramEditorComponentInfo>& compos,
int nLayout,
int nSource,
bool saveToModel) {
// 1. 创建配置
LayoutConfig config(nLayout);
config.setSpacing(Constants::V_DIAGRAM_SPACING,
Constants::H_DIAGRAM_SPACING);
// 2. 创建引擎和上下文
DiagramLayoutEngine engine(this);
DiagramLayoutEngine::Context context;
context.sourceId = nSource;
context.saveToModel = saveToModel;
// 3. 执行布局
QRectF boundingRect = engine.executeLayout(data, compos, config, context);
return boundingRect;
}
/*QRectF DiagramEditorModel::updateTarget(QMap<QString,DiagramEditorRouteInfo>& data,QMap<QString,DiagramEditorComponentInfo>& compos,int nLayout,int nSource,bool saveToModel)
{ {
QRectF recBounding; //包含所有元件的矩形 QRectF recBounding; //包含所有元件的矩形
auto& mapRoute = data; auto& mapRoute = data;
@ -2082,39 +1927,6 @@ QRectF DiagramEditorModel::updateTarget(QMap<QString,DiagramEditorRouteInfo>& da
} }
if(!route.lstCompo.isEmpty()){ //拆分线路为以节点为首 if(!route.lstCompo.isEmpty()){ //拆分线路为以节点为首
/*auto pItemFirst = getNameItem(route.lstCompo.first().sName,nSource);
int nFirstVal = pItemFirst->data().toInt();
auto pItemLast = getNameItem(route.lstCompo.last().sName,nSource);
int nLastVal = pItemLast->data().toInt();
if(nFirstVal != 0){ //首位为节点
route.lstOrder = route.lstCompo;
}
else if(nLastVal != 0){ //末位为节点
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
route.lstReverse.append(*it);
}
}
else{ //节点在中间
int nIndex = 0;
for(int i = 0;i < route.lstCompo.size();++i){
auto pItem = getNameItem(route.lstCompo[i].sName,nSource);
if(pItem){
int nVal = pItem->data().toInt();
if(nVal != 0){
nIndex = i;
break;
}
}
}
for(int i = nIndex;i >= 0;--i){
route.lstReverse.append(route.lstCompo[i]);
}
for(int i = nIndex;i < route.lstCompo.size();++i){
route.lstOrder.append(route.lstCompo[i]);
}
}*/
if(saveToModel){ if(saveToModel){
auto pItemFirst = getNameItem(route.lstCompo.first().sName,nSource); auto pItemFirst = getNameItem(route.lstCompo.first().sName,nSource);
int nFirstVal = pItemFirst->data().toInt(); int nFirstVal = pItemFirst->data().toInt();
@ -2561,7 +2373,7 @@ QRectF DiagramEditorModel::updateTarget(QMap<QString,DiagramEditorRouteInfo>& da
} }
} }
return recBounding; return recBounding;
} }*/
void DiagramEditorModel::bulidAndLinkComponent(QList<DiagramEditorComponentInfo> lst,QMap<QString,DiagramEditorComponentInfo> components,DiagramEditorBaseBlock* pParent) void DiagramEditorModel::bulidAndLinkComponent(QList<DiagramEditorComponentInfo> lst,QMap<QString,DiagramEditorComponentInfo> components,DiagramEditorBaseBlock* pParent)
{ {

View File

@ -313,7 +313,7 @@ QPushButton:disabled {
<item row="2" column="1"> <item row="2" column="1">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
<string>设备</string> <string>间隔设备</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin"> <property name="leftMargin">

View File

@ -313,7 +313,7 @@ QPushButton:disabled {
<item row="2" column="1"> <item row="2" column="1">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
<string>设备</string> <string>间隔设备</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin"> <property name="leftMargin">