diff --git a/common/include/global.h b/common/include/global.h index 66dee24..eb78939 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -417,7 +417,8 @@ enum class EditorItemType //组态编辑中的图形项类型 { bus = 0, //母线 bay, //间隔 - Trans, //变压器 + trans, //变压器 + line, //连接线 none //空白占位图 }; diff --git a/diagramCavas/include/diagramEditor/diagramEditorWizard.h b/diagramCavas/include/diagramEditor/diagramEditorWizard.h index 1212723..84490d5 100644 --- a/diagramCavas/include/diagramEditor/diagramEditorWizard.h +++ b/diagramCavas/include/diagramEditor/diagramEditorWizard.h @@ -50,6 +50,7 @@ public: QList getTargetLevelBlocks(int nLevel,int nType); //返回指定层数的对应block,type:1母线,2间隔,3变压器 QList getTargetLevelBlocks_all(int nLevel); DiagramEditorStructContainer* getContainerByBlock(int nLevel,int nType,QString sName); //根据block名称返回container nType:1母线2间隔3变压器 + DiagramEditorStructContainer* getContainerByBlock_all(QString sName); DiagramEditorBaseBlock* getBlockByName(int nLevel,int nType,QString sName); //根据名称返回block DiagramEditorBaseBlock* getBlockByName_all(QString sName); bool removeBlockByName(int nLevel,int nType,const QString& sName); //依据名称删除block diff --git a/diagramCavas/include/diagramEditor/editItems.h b/diagramCavas/include/diagramEditor/editItems.h index 28b0233..5ef7b78 100644 --- a/diagramCavas/include/diagramEditor/editItems.h +++ b/diagramCavas/include/diagramEditor/editItems.h @@ -39,6 +39,7 @@ class EditBusItem: public EditBaseItem public: EditBusItem(QGraphicsItem *parent = nullptr); virtual ~EditBusItem(); + virtual void setGeometry(const QRectF &rect) override; protected: virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; }; @@ -65,4 +66,29 @@ protected: virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; }; +/********************连线*********************/ +class EditLineItem : public EditBaseItem +{ +public: + EditLineItem(QGraphicsItem *parent = nullptr); + virtual ~EditLineItem(); + + void setStartPoint(const QPointF& p); + void setEndPoint(const QPointF& p); + QPainterPath getPoints(void) const { return m_points; } + + void calculatePath(int nSeg = 2); //划分段数,2段3段 + void resetCurLine(){_curLine = QPoint();} + +protected: + virtual QPainterPath shape() const override; + virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; +private: + QPainterPath m_points; + QPainterPath m_pointsBoundingRect; //包裹点的矩形集合 + QList m_lstPoints; + QPoint _curLine; //参数1用点序号表示的当前线段起始点,参数2表示线段方向 + +}; + #endif diff --git a/diagramCavas/include/diagramEditor/editPanel.h b/diagramCavas/include/diagramEditor/editPanel.h index 1af0cd1..023e983 100644 --- a/diagramCavas/include/diagramEditor/editPanel.h +++ b/diagramCavas/include/diagramEditor/editPanel.h @@ -2,6 +2,7 @@ #define EDITPANEL_H //编辑文本项生成组态图 #include +#include #include "global.h" class EditView; @@ -15,6 +16,7 @@ class EditRowData; class EditContainerItem; class DiagramEditorWizard; class DiagramEditorBaseBlock; +class EditBaseItem; class EditPanel : public QWidget { @@ -24,7 +26,8 @@ public: ~EditPanel(); void initByWizardInfo(); - void setOperateWizard(DiagramEditorWizard* p) {_curWizard = p;} + void initBlockConnection(); //初始化block之间的连接信息 + void setOperateWizard(QPointer p) {_curWizard = p;} public slots: void onWidthChanged(int width); void onContainerSizeChanged(EditContainerItem*); //容器大小改变时调整内部大小 @@ -32,19 +35,19 @@ private: void initial(); void calculateContainerWidth(EditContainerItem*); //根据间隔数量计算容器宽度 todo:区分上下间隔 int getContainerBusType(QMap>); //返回容器中母线类型(单双) + EditBaseItem* getItemByName(const QString&); //根据名称获取指定item private: EditView* m_pEditView; EditScene* m_pEditScene; QVBoxLayout* _layout; EditMainRect* _mainWidget; - //QGraphicsGridLayout* _widgetLayout; QGraphicsLinearLayout* _widgetLayout; QGraphicsProxyWidget* m_addBtnPro; int _maxWidth; int _maxHeight; QList _lstData; QMap> _mapStruct; - DiagramEditorWizard* _curWizard; + QPointer _curWizard; }; #endif diff --git a/diagramCavas/source/diagramEditor/diagramEditorWizard.cpp b/diagramCavas/source/diagramEditor/diagramEditorWizard.cpp index 0c91590..7b0bfa2 100644 --- a/diagramCavas/source/diagramEditor/diagramEditorWizard.cpp +++ b/diagramCavas/source/diagramEditor/diagramEditorWizard.cpp @@ -521,6 +521,10 @@ void DiagramEditorWizard::onAddBayFinished(DiagramEditorWizardBayInfo info) } } } + else if(info.nType == BayType::outcomingBay){ //出线间隔 + auto pContainer = getContainerByBlock(curIndex,1,info.lstBindObj.first()); + pContainer->insertBlock(0,pBlock); + } else{ //其他间隔 auto pContainer = getContainerByBlock(curIndex,1,info.lstBindObj.first()); pContainer->insertBlock(3,pBlock); @@ -811,6 +815,22 @@ DiagramEditorStructContainer* DiagramEditorWizard::getContainerByBlock(int nLeve return pContainer; } +DiagramEditorStructContainer* DiagramEditorWizard::getContainerByBlock_all(QString sName) +{ + DiagramEditorStructContainer* pContainer = nullptr; + for(auto iter = _mapSturctContainer.begin(); iter != _mapSturctContainer.end();++iter){ + auto lstBlock = getTargetLevelBlocks_all(iter.key()); + for(auto& block:lstBlock){ + if(block->getName() == sName){ + pContainer = block->getCurContainer(); + break; + } + } + } + + return pContainer; +} + DiagramEditorBaseBlock* DiagramEditorWizard::getBlockByName(int nLevel,int nType,QString sName) { auto lstBlock = getTargetLevelBlocks(nLevel,nType); diff --git a/diagramCavas/source/diagramEditor/editItems.cpp b/diagramCavas/source/diagramEditor/editItems.cpp index 4639c75..f9a77a1 100644 --- a/diagramCavas/source/diagramEditor/editItems.cpp +++ b/diagramCavas/source/diagramEditor/editItems.cpp @@ -30,6 +30,14 @@ EditBusItem::~EditBusItem() } +void EditBusItem::setGeometry(const QRectF &rect) +{ + prepareGeometryChange(); + + QGraphicsWidget::setGeometry(rect); + +} + void EditBusItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { painter->fillRect(m_boundingRect,Qt::black); @@ -73,3 +81,110 @@ void EditTransItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt painter->drawRect(m_boundingRect); painter->drawText(QPointF(-10,0),sName); } + +/********************连线*********************/ + +EditLineItem::EditLineItem(QGraphicsItem *parent) + : EditBaseItem(parent) +{ + m_boundingRect = QRectF(); + m_lstPoints.push_back(QPointF()); //起点 + m_lstPoints.push_back(QPointF()); //终点 + _curLine = QPoint(); +} + +EditLineItem::~EditLineItem() +{ +} + +void EditLineItem::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()); + } + } + m_lstPoints[0] = p; + } +} +void EditLineItem::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; + } +} + +QPainterPath EditLineItem::shape() const +{ + QPainterPath path; + path.addPath(m_pointsBoundingRect); + return path; +} + +void EditLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + painter->setPen(Qt::black); + + painter->drawPath(m_points); +} + +void EditLineItem::calculatePath(int nSeg) +{ + prepareGeometryChange(); + m_points.clear(); + m_pointsBoundingRect.clear(); + + if(m_lstPoints.size() == 2 && (m_lstPoints.first().x() != m_lstPoints.last().x()) && (m_lstPoints.first().y() != m_lstPoints.last().y())) + { + if(nSeg == 2) + { + /*if(m_lstPoints.first().y() < m_lstPoints.last().y()) + m_lstPoints.insert(1,QPointF(m_lstPoints.first().x(),m_lstPoints.last().y())); + else + m_lstPoints.insert(1,QPointF(m_lstPoints.last().x(),m_lstPoints.first().y()));*/ + m_lstPoints.insert(1,QPointF(m_lstPoints.last().x(),m_lstPoints.first().y())); + } + else + { + const QPointF p1 = m_lstPoints.first(); + const QPointF p2 = m_lstPoints.last(); + + const qreal dx = (p2.x() - p1.x()) / 3; + const qreal dy = (p2.y() - p1.y()) / 3; + m_lstPoints.insert(1, QPointF(p1.x(), p1.y() + dy)); + m_lstPoints.insert(2, QPointF(p2.x(), p1.y() + dy)); + } + } + + m_points.moveTo(m_lstPoints.first()); + QPointF pLast = m_lstPoints.first(); + for(int i = 1;i #include #include +#include #include #include "diagramEditor/editPanel.h" #include "diagramEditor/editScene.h" @@ -49,7 +50,7 @@ void EditPanel::initByWizardInfo() continue; QGraphicsLinearLayout* layoutRowData = new QGraphicsLinearLayout(Qt::Horizontal); layoutRowData->setSpacing(20); - //layoutRowData->setMinimumHeight(300); + layoutRowData->setMaximumHeight(300); EditRowData* pRow = new EditRowData(); pRow->setId(QString::number(iter.key())); auto& mapCon = iter.value(); @@ -122,14 +123,21 @@ void EditPanel::initByWizardInfo() pSpace->setBoundingRect(QRectF(0,0,g_dEditorItem_Width,g_dEditorItem_Height)); layH->addItem(pSpace); } - layV->insertStretch(3); - layV->insertStretch(1); + if(layV->count() == 4){ + layV->insertStretch(3); + layV->insertStretch(1); + } + else if(layV->count() == 2) + { + layV->insertStretch(1); + } + calculateContainerWidth(pContain); - int n = getContainerBusType(mapBlock); + /*int n = getContainerBusType(mapBlock); if(n == 1){ layoutRowData->setMaximumHeight(210); - } + }*/ } _lstData.append(pRow); //layoutRowData->addStretch(); @@ -168,7 +176,7 @@ void EditPanel::initByWizardInfo() if(nType == 3){ //变压器 auto pTrans = new EditTransItem(); - pTrans->setType(EditorItemType::Trans); + pTrans->setType(EditorItemType::trans); pTrans->setBoundingRect(QRectF(0,0,g_dEditorItem_Width,g_dEditorItem_Width)); pItem = pTrans; } @@ -192,6 +200,124 @@ void EditPanel::initByWizardInfo() } } _widgetLayout->addStretch(); + QTimer::singleShot(300, [&]() { // 1000 毫秒 = 1 秒 + qDebug() << "一次性定时器触发!"; + initBlockConnection(); + }); +} + +void EditPanel::initBlockConnection() +{ + if(_curWizard){ + auto mapCon = _curWizard->getConnection(); + //todo:添加过的不再添加 + for(auto& con:mapCon){ + auto item1 = _curWizard->getBlockByName_all(con.con1.sName); + auto item2 = _curWizard->getBlockByName_all(con.con2.sName); + + auto con1 = _curWizard->getContainerByBlock_all(con.con1.sName); + auto con2 = _curWizard->getContainerByBlock_all(con.con2.sName); + + 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()); + pLine->setType(EditorItemType::line); + m_pEditScene->addItem(pLine); + if(con1 && con2){ + + int nT1 = item1->getType(); + int nT2 = item2->getType(); + + QPointF center1 = pItem1->scenePos(); + QPointF center2 = pItem2->scenePos(); + + if(con1 == con2){ //两个block在同一个容器中(上下连接) + + center1 += QPointF(pItem1->boundingRect().width()*0.5,0); + center2 += QPointF(pItem2->boundingRect().width()*0.5,0); + + if((nT1 == 1 && nT2 == 2) || (nT2 == 1 && nT1 == 2)){ //对象是母线段,母线横坐标与同容器Block相同 + if(nT1 == 1){ //pItem1是母线 + center1.setX(center2.x()); + } + else{ //pItem2是母线 + center2.setX(center1.x()); + } + + if(center1.y() < center2.y()){ //item1在item2上 2的上边连接1下边 + center1 += QPointF(0,pItem1->boundingRect().height()); //将1的点移动到下边 + } + else{ //2在1上 + center2 += QPointF(0,pItem2->boundingRect().height()); //将2的点移动到下边 + } + pLine->setStartPoint(center1); + pLine->setEndPoint(center2); + pLine->calculatePath(); + } + } + else{ + if((nT1 == 1 && nT2 == 2) || (nT2 == 1 && nT1 == 2)){ //分段连接(左右连接) + center1 += QPointF(0,pItem1->boundingRect().height()*0.5); + center2 += QPointF(0,pItem2->boundingRect().height()*0.5); + if(center1.x() < center2.x()){ //item1在item2左边 1右连2左 + center1 += QPointF(pItem1->boundingRect().width(),0); + } + else{ //1在2右 2右连1左 + center2 += QPointF(pItem2->boundingRect().width(),0); + } + pLine->setStartPoint(center1); + pLine->setEndPoint(center2); + pLine->calculatePath(); + } + else if((nT1 == 3 && nT2 == 2) || (nT2 == 2 && nT1 == 3)){ //变压器连间隔 + center1 += QPointF(pItem1->boundingRect().width()*0.5,0); + center2 += QPointF(pItem2->boundingRect().width()*0.5,0); + + DiagramEditorTransformerBlock* pTrans = nullptr; + DiagramEditorBayBlock* pBay = nullptr; + if(nT1 == 3){ + pTrans = dynamic_cast(item1); + pBay = dynamic_cast(item2); + } + else if(nT2 == 3){ + pTrans = dynamic_cast(item2); + pBay = dynamic_cast(item1); + } + + if(pTrans && pBay){ + TransformerType typTrans = pTrans->getTransType(); + BayType typBay = pBay->getBayType(); + if(typTrans == TransformerType::twoWinding){ //两绕组 + if(typBay == BayType::incomingBay){ //进线间隔,在高压侧 + center2 += QPointF(0,pItem2->boundingRect().height()); + } + else if(typBay == BayType::outcomingBay){ //出线间隔,在低压侧 + center1 += QPointF(0,pItem1->boundingRect().height()); + } + } + else{ //三绕组 //todo:手动区分三绕组 + + } + } + pLine->setStartPoint(center1); + pLine->setEndPoint(center2); + pLine->calculatePath(3); + } + } + } + + } + } } void EditPanel::onWidthChanged(int width) @@ -293,3 +419,17 @@ int EditPanel::getContainerBusType(QMap> map) return 1; } } + +EditBaseItem* EditPanel::getItemByName(const QString& sName) +{ + auto lstItems = m_pEditScene->items(); + for(auto& item:lstItems){ + auto pBase = dynamic_cast(item); + if(pBase){ + if(pBase->getName() == sName){ + return pBase; + } + } + } + return nullptr; +} diff --git a/diagramCavas/ui/diagramEditorTransSettingDlg.ui b/diagramCavas/ui/diagramEditorTransSettingDlg.ui index e4724a7..1594282 100644 --- a/diagramCavas/ui/diagramEditorTransSettingDlg.ui +++ b/diagramCavas/ui/diagramEditorTransSettingDlg.ui @@ -142,45 +142,11 @@ 20 - + 10 - - - - - - - 间隔位置 - - - - - - - 间隔类型 - - - - - - - - - - - 进线间隔 - - - - - 出线间隔 - - - - - + 10 @@ -208,6 +174,66 @@ + + + + 间隔位置 + + + + + + + 间隔类型 + + + + + + + + + + + 进线间隔 + + + + + 出线间隔 + + + + + + + + + + + 连接到 + + + + + + + + 高压侧 + + + + + 中压侧 + + + + + 低压侧 + + + +