#include "monitorPanel.h" #include #include #include #include #include #include #include "graphicsDataModel/fixedPortsModel.h" #include "graphicsItem/graphicsBaseItem.h" #include "powerEntity.h" #include "statusBar.h" #include "baseProperty.h" #include "graphicsItem/electricBayItem.h" #include "monitorSideBarDlg.h" #include "monitorSelectedItemsDlg.h" #include "monitorConfigDlg.h" #include "monitorAttributeDlg.h" #include "monitorDetailAttributeDlg.h" #include "monitorDisplaySettingDlg.h" #include "dataBase.h" #include "projectModelManager.h" MonitorPanel::MonitorPanel(PowerEntity* pEntity,QWidget *parent,DiagramMode mode) : BaseDrawingPanel(pEntity,parent,mode) ,_toolBar(nullptr) ,_sideBar(nullptr) ,_pConfigDlg(nullptr) ,_itemListmodel(nullptr) ,_menuSetting(nullptr) ,_detailAttributeDlg(nullptr) ,_displaySettingDlg(nullptr) { m_pStatusBar->setButtonVisible(false); initial(); } MonitorPanel::~MonitorPanel() { } void MonitorPanel::initial() { _itemListmodel = new QStandardItemModel(this); createToolBar(); _sideBar = new MonitorSideBarDlg(this); _hSplitter->addWidget(_sideBar); _sideBar->show(); _pConfigDlg = new MonitorConfigDlg(this); _detailAttributeDlg = new MonitorDetailAttributeDlg(this); _displaySettingDlg = new MonitorDisplaySettingDlg(this); } void MonitorPanel::closeEvent(QCloseEvent *closeEvent) { emit panelDelete(_name,2); } void MonitorPanel::createToolBar() { _toolBar = new QToolBar(this); _toolBar->setStyleSheet("QToolBar { background-color: palette(window); border: none; }"); QAction *runAction = new QAction("运行", this); connect(runAction, &QAction::triggered, this, &MonitorPanel::onRunClicked); _toolBar->addAction(runAction); QAction *stopAction = new QAction("停止", this); connect(stopAction, &QAction::triggered, this, &MonitorPanel::onStopClicked); _toolBar->addAction(stopAction); QAction *configAction = new QAction("参数配置", this); connect(configAction, &QAction::triggered, this, &MonitorPanel::onConfigClicked); _toolBar->addAction(configAction); QAction *itemConfigAction = new QAction("图元配置", this); connect(itemConfigAction, &QAction::triggered, this, &MonitorPanel::onItemConfigClicked); _toolBar->addAction(itemConfigAction); QAction *connectAction = new QAction("连接设置", this); connect(connectAction, &QAction::triggered, this, &MonitorPanel::onConncecClicked); _toolBar->addAction(connectAction); QAction *otherAction = new QAction("其他设置", this); _menuSetting = new QMenu(this); QAction *toggleAction = _menuSetting->addAction("显示属性"); toggleAction->setCheckable(true); // 连接菜单项点击事件 connect(toggleAction, &QAction::triggered, this, [this]() { _sideBar->setVisible(!_sideBar->isVisible()); }); // 在显示菜单前同步菜单项状态 connect(_menuSetting, &QMenu::aboutToShow, this, [this, toggleAction]() { toggleAction->setChecked(_sideBar->isVisible()); }); connect(otherAction, &QAction::triggered, this, [&]() { QWidget *widget = _toolBar->widgetForAction(otherAction); if (widget) { QPoint pos = widget->mapToGlobal(QPoint(0, widget->height())); _menuSetting->exec(pos); } else { _menuSetting->exec(QCursor::pos()); } }); _toolBar->addAction(otherAction); // 设置工具栏样式 _toolBar->setToolButtonStyle(Qt::ToolButtonTextOnly); _verticalLayout->setMenuBar(_toolBar); } QJsonObject MonitorPanel::getMonitorInfo() const { QJsonObject obj; QJsonArray arr; if(_pModel) { QMap map = _pModel->allNodePos(); for(auto iter = map.begin();iter != map.end();++iter) { QJsonObject node; node["id"] = iter.key().toString(); node["x"] = iter.value().pos.x(); node["y"] = iter.value().pos.y(); node["width"] = iter.value().dWidth; node["height"] = iter.value().dHeight; node["rotate"] = iter.value().dRotate; arr.append(node); } obj["nodes"] = arr; QJsonArray arrConnect; QVector vec = _pModel->allConnectionProperty(); for(auto& pPro:vec){ Connection con = pPro->getConnection(); QJsonObject connect; connect["id"] = pPro->uuid().toString(); connect["SrcNodeId"] = con.nSrcNodeId.toString(); connect["SrcPortId"] = con.nSrcPortId.toString(); connect["DestNodeId"] = con.nDestNodeId.toString(); connect["DestPortId"] = con.nDestPortId.toString(); arrConnect.append(connect); } obj["connections"] = arrConnect; QJsonArray arrBay; QMap mapBay = _pModel->allBayItem(); for(auto& bayItem:mapBay){ AbstractProperty* pPro = bayItem->getProperty(); BayProperty* pBay = dynamic_cast(pPro); if(pBay) { QJsonObject bay; bay["id"] = pBay->uuid().toString(); arrBay.append(bay); } } obj["bays"] = arrBay; auto relation = serializeRelationToJsonArray(_pModel->getMonitorRelation()); obj["relation"] = relation; auto para = serializeParaToJsonArray(_pModel->getMonitorPara()); //设定参数 obj["para"] = para; auto settingArr = serializeDisplayToJsonArray(_pModel->getMonitorDisplaySetting()); //显示参数 obj["displaySetting"] = settingArr; } return obj; } void MonitorPanel::loadNodes(QJsonObject obj) { QJsonArray nodesJsonArray = obj["nodes"].toArray(); QList> lst; for (QJsonValueRef nodeJson : nodesJsonArray) { QJsonObject node = nodeJson.toObject(); QString uuid = node["id"].toString(); double dX = node["x"].toDouble(); double dY = node["y"].toDouble(); double dWidth = node["width"].toDouble(); double dHeight = node["height"].toDouble(); double dRotate = node["rotate"].toDouble(); if(_pModel) { QString sName = _pModel->addNodeItem(QUuid(uuid),QPointF(dX,dY),dWidth,dHeight,dRotate); if(sName != "err"){ lst.append(qMakePair(sName,QUuid(uuid))); } } } QJsonArray connectArr = obj["connections"].toArray(); for(QJsonValueRef connectJson:connectArr) { QJsonObject connect = connectJson.toObject(); QUuid id = QUuid(connect["id"].toString()); //电缆线id,关联component中的电缆 QUuid srcId = QUuid(connect["SrcNodeId"].toString()); QUuid srcPortId = QUuid(connect["SrcPortId"].toString()); QUuid destId = QUuid(connect["DestNodeId"].toString()); QUuid destPortId = QUuid(connect["DestPortId"].toString()); PowerConnection* pCon = TopologyManager::instance().connection(srcPortId.toString(),destPortId.toString()); if(pCon) { QString srcItemId = pCon->fromComponent(); QString destItemId = pCon->toComponent(); //todo:从拓扑结构中查找port的id if(_pModel) { QString sName = _pModel->addConnectLline(id,QUuid(srcItemId),QUuid(destItemId),srcPortId,destPortId); if(sName != "err"){ lst.append(qMakePair(sName,QUuid(id))); } } } else { //todo:提示拓扑结构已改变 } } QJsonArray bayArr = obj["bays"].toArray(); for(QJsonValueRef bayJson:bayArr) { QJsonObject bay = bayJson.toObject(); QUuid id = QUuid(bay["id"].toString()); if(_pModel) { _pModel->addBayItem(id); } } QJsonArray paraArr = obj["para"].toArray(); QMap> mapPara; bool resPara = deserializeParaFromJsonArray(paraArr,mapPara); if(resPara){ if(_pModel){ _pModel->setMonitorPara(mapPara); auto pItems = _pModel->getProjectItems(); for(auto& p:pItems){ //将设置值更新到每个item auto pPro = p->getProperty(); if(pPro) _pModel->monitorItemSet(pPro->uuid()); } } } QJsonArray displayArr = obj["displaySetting"].toArray(); QMap> mapDisplay; deserializeDisplayFromJsonArray(displayArr,mapDisplay); if(_pModel){ _pModel->setMonitorDisplaySetting(mapDisplay); _pModel->updateMonitorDisplay(); } QJsonArray relationArr = obj["relation"].toArray(); QList lstRelation; bool resRel = deserializeRelationFromJsonArray(relationArr, lstRelation); if(resRel){ QList lstFirst; if(_pModel){ auto pItems = _pModel->getProjectItems(); for(auto& itemInfo:lstRelation) { if(itemInfo.item.nCategory == 0){ //设备 if(pItems.contains(itemInfo.item.uid)){ if(itemInfo.item.nEquipType == 1 || itemInfo.item.nEquipType == 15 || itemInfo.item.nEquipType == 16){ //先添加母线及独立设备 lstFirst.append(itemInfo); } } } } QList lstSecond; for(auto& itemInfo:lstRelation) //第二次循环处理间隔内设备 { if(itemInfo.item.nCategory == 0){ //间隔 if(pItems.contains(itemInfo.item.uid)){ if(itemInfo.item.nEquipType != 1 && itemInfo.item.nEquipType != 15 && itemInfo.item.nEquipType != 16){ lstSecond.append(itemInfo); } } } } updateSelectedItems(lstFirst,true); //直接生成监控tree updateSelectedItems(lstSecond,false); _pModel->setMonitorRelation(lstRelation); } } } void MonitorPanel::saveNodes(int pageId) { } void MonitorPanel::updateSelectedItems(QList lst,bool val) { if(val){ QStandardItem *root = _itemListmodel->invisibleRootItem(); int rowCount = root->rowCount(); if (rowCount > 0) { _itemListmodel->removeRows(0, rowCount); } } for(auto &info:lst){ auto curItem = info.item; if(curItem.nCategory == 0){ if(curItem.nEquipType == 1 || curItem.nEquipType == 15 || curItem.nEquipType == 16){ //母线与变压器等间隔外设备并列第一层 QStandardItem *pItem = new QStandardItem(curItem.sName); pItem->setData(curItem.nCategory,Qt::UserRole+1); pItem->setData(curItem.nEquipType,Qt::UserRole+2); pItem->setData(curItem.uid,Qt::UserRole+3); for(auto& subInfo:info.subList){ //母线挂接间隔,变压器挂接设备 QStandardItem *pSub = new QStandardItem(subInfo.sName); pSub->setData(subInfo.nCategory,Qt::UserRole+1); pSub->setData(subInfo.nEquipType,Qt::UserRole+2); pSub->setData(subInfo.uid,Qt::UserRole+3); pItem->appendRow(pSub); } _itemListmodel->appendRow(pItem); } else{ //其他设备挂接在母线下的间隔中 if(!info.parent.sName.isEmpty()){ //有父,在间隔内 QStandardItem *pItem = new QStandardItem(curItem.sName); pItem->setData(curItem.nCategory,Qt::UserRole+1); pItem->setData(curItem.nEquipType,Qt::UserRole+2); pItem->setData(curItem.uid,Qt::UserRole+3); auto pParent = findStandardItemAtLevel(_itemListmodel,1,info.parent.sName,nullptr,0); //查找父间隔所在item if(pParent){ pParent->appendRow(pItem); } else{ //一层没找到父 QStandardItem *pPar = nullptr; pPar = findStandardItemAtLevel(_itemListmodel,0,info.parent.sName,nullptr,0); if(pPar){ //顶层中找到 pPar->appendRow(pItem); //将自己挂到父下 } else{ //顶层未找到,新建 pPar = new QStandardItem(info.parent.sName); pPar->setData(info.parent.nCategory,Qt::UserRole+1); pPar->setData(info.parent.nEquipType,Qt::UserRole+2); pPar->setData(info.parent.uid,Qt::UserRole+3); _itemListmodel->appendRow(pPar); pPar->appendRow(pItem); //将自己挂到父下 } } } } } } _sideBar->getItemsDlg()->updateItems(); _pConfigDlg->updateSelectedItems(); } void MonitorPanel::initMonitorConfig() { } void MonitorPanel::itemSelected(QUuid uid) { _sideBar->getAttributeDlg()->clearAllGroup(); _sideBar->getAttributeDlg()->generateAttributeGroups(uid); } void MonitorPanel::detailItemSelected(QUuid uid) { _detailAttributeDlg->show(); _detailAttributeDlg->generateAttributeGroups(uid); } void MonitorPanel::onRunClicked() { } void MonitorPanel::onStopClicked() { } void MonitorPanel::onConfigClicked() { _pConfigDlg->show(); } void MonitorPanel::onItemConfigClicked() { _displaySettingDlg->showDlg(); } void MonitorPanel::onConncecClicked() { } void MonitorPanel::initDisplayState() { auto &mapState = _pModel->getMonitorStateMap(); QList> lst_bus; lst_bus.append(qMakePair(monitorItemState::Normal,"正常")); lst_bus.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_bus.append(qMakePair(monitorItemState::Energized,"带电")); lst_bus.append(qMakePair(monitorItemState::DeEnergized,"失电")); lst_bus.append(qMakePair(monitorItemState::Grounding,"接地")); mapState.insert(1,lst_bus); QList> lst_asyncmotor; lst_asyncmotor.append(qMakePair(monitorItemState::Normal,"正常")); lst_asyncmotor.append(qMakePair(monitorItemState::Alarm,"告警")); lst_asyncmotor.append(qMakePair(monitorItemState::LineBreak,"断线")); lst_asyncmotor.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(2,lst_asyncmotor); QList> lst_cb; lst_cb.append(qMakePair(monitorItemState::Normal,"正常")); lst_cb.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_cb.append(qMakePair(monitorItemState::Closing,"合闸")); lst_cb.append(qMakePair(monitorItemState::Opening,"分闸")); lst_cb.append(qMakePair(monitorItemState::AccidentTrip,"事故跳闸")); mapState.insert(3,lst_cb); QList> lst_ct; lst_ct.append(qMakePair(monitorItemState::Normal,"正常")); lst_ct.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_ct.append(qMakePair(monitorItemState::LineBreak,"断线")); mapState.insert(4,lst_ct); QList> lst_pt; lst_pt.append(qMakePair(monitorItemState::Normal,"正常")); lst_pt.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_pt.append(qMakePair(monitorItemState::LineBreak,"断线")); mapState.insert(5,lst_pt); QList> lst_es; lst_es.append(qMakePair(monitorItemState::Normal,"正常")); lst_es.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_es.append(qMakePair(monitorItemState::Closing,"合闸")); lst_es.append(qMakePair(monitorItemState::Opening,"分闸")); mapState.insert(6,lst_es); QList> lst_fes; lst_fes.append(qMakePair(monitorItemState::Normal,"正常")); lst_fes.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_fes.append(qMakePair(monitorItemState::Closing,"合闸")); lst_fes.append(qMakePair(monitorItemState::Opening,"分闸")); mapState.insert(7,lst_fes); QList> lst_cable; lst_cable.append(qMakePair(monitorItemState::Normal,"正常")); lst_cable.append(qMakePair(monitorItemState::Energized,"带电")); lst_cable.append(qMakePair(monitorItemState::DeEnergized,"失电")); lst_cable.append(qMakePair(monitorItemState::Grounding,"接地")); mapState.insert(8,lst_cable); QList> lst_ds; lst_ds.append(qMakePair(monitorItemState::Normal,"正常")); lst_ds.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_ds.append(qMakePair(monitorItemState::Closing,"合闸")); lst_ds.append(qMakePair(monitorItemState::Opening,"分闸")); mapState.insert(9,lst_ds); QList> lst_dteds; lst_dteds.append(qMakePair(monitorItemState::Normal,"正常")); lst_dteds.append(qMakePair(monitorItemState::StatusFault,"故障")); lst_dteds.append(qMakePair(monitorItemState::Closing,"合闸")); lst_dteds.append(qMakePair(monitorItemState::Opening,"分闸")); mapState.insert(10,lst_dteds); QList> lst_potentialIndicator; lst_potentialIndicator.append(qMakePair(monitorItemState::Normal,"正常")); lst_potentialIndicator.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(11,lst_potentialIndicator); QList> lst_lightningArrester; lst_lightningArrester.append(qMakePair(monitorItemState::Normal,"正常")); lst_lightningArrester.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(12,lst_lightningArrester); QList> lst_cableTermination; lst_cableTermination.append(qMakePair(monitorItemState::Normal,"正常")); lst_cableTermination.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(13,lst_cableTermination); QList> lst_cableEnd; lst_cableEnd.append(qMakePair(monitorItemState::Normal,"正常")); lst_cableEnd.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(14,lst_cableEnd); QList> lst_transformer2w; lst_transformer2w.append(qMakePair(monitorItemState::Normal,"正常")); lst_transformer2w.append(qMakePair(monitorItemState::Alarm,"告警")); lst_transformer2w.append(qMakePair(monitorItemState::LineBreak,"断线")); lst_transformer2w.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(15,lst_transformer2w); QList> lst_transformer3w; lst_transformer3w.append(qMakePair(monitorItemState::Normal,"正常")); lst_transformer3w.append(qMakePair(monitorItemState::Alarm,"告警")); lst_transformer3w.append(qMakePair(monitorItemState::LineBreak,"断线")); lst_transformer3w.append(qMakePair(monitorItemState::StatusFault,"故障")); mapState.insert(16,lst_transformer3w); } void MonitorPanel::initDisplaySetting() { auto stateMap = _pModel->getMonitorStateMap(); QMap mapType = DataBase::GetInstance()->getAllComponentType(); //所有类型 QMap mapUsed; //本图中使用的类型、模型名 auto mapItems = getModelController()->getProjectItems(); for(auto& pItem:mapItems){ auto pPro = pItem->getProperty(); if(pPro){ QString sMeta = pPro->metaModelName(); QString sModel = pPro->modelName(); int nType = pPro->type(); if(!mapUsed.contains(nType)){ ModelTypeInfo info; info.nType = nType; info.sType = mapType.value(nType).type; info.sName = mapType.value(nType).name; info.sMeta = sMeta; info.sModel = sModel; mapUsed.insert(nType,info); } } } QMap mapAllType = DataBase::GetInstance()->ModelType(); for(auto iter = mapUsed.begin();iter != mapUsed.end();++iter){ //遍历所有类型 QMap mapStates; QString sType = mapUsed.value(iter.key()).sType; QString sName = mapUsed.value(iter.key()).sName; QString sMeta = mapUsed.value(iter.key()).sMeta; QString sModel = mapUsed.value(iter.key()).sModel; QList> lstState = stateMap.value(iter.key()); for(auto &pair:lstState){ monitorItemDisplayInfo info; info.nItemType = iter.key(); info.sStateName = pair.second; info.sMeta = sMeta; info.sModel = sModel; info.nWidth = 40; info.nHeight = 40; QByteArray svg; auto mapUsedSvg = ProjectModelManager::instance().getData()[sMeta][sModel].modelSetting.mapUsedSvg; auto mapAllSvg = ProjectModelManager::instance().getData()[sMeta][sModel].modelSetting.mapSvg; if(!mapUsedSvg.empty()){ //先判断已选svg svg = mapUsedSvg.first(); } else if(!mapAllSvg.empty()){ //后判断所有svg svg = mapAllSvg.first(); } else { for(auto &mt:mapAllType){ //最后采用初始svg if(mt.modelName == iter->sName){ svg = mt.icon; break; } } } info.bytPicture = svg; monitorItemStateStruct keyState; keyState.eState = pair.first; keyState.sState = pair.second; mapStates.insert(keyState,info); } monitorItemTypeStruct keyType; keyType.sTag = sType; keyType.sName = sName; _pModel->getMonitorDisplaySetting().insert(keyType,mapStates); } } QJsonArray MonitorPanel::serializeRelationToJsonArray(const QList& data) const { QJsonArray rootArray; for (const auto& relationItem : data) { rootArray.append(relationItem.toJson()); } return rootArray; } // 从 QJsonArray 反序列化到 QList bool MonitorPanel::deserializeRelationFromJsonArray(const QJsonArray& jsonArray, QList& result) { result.clear(); for (const QJsonValue& itemValue : jsonArray) { if (!itemValue.isObject()) continue; monitorRelationItem relationItem; relationItem.fromJson(itemValue.toObject()); if (relationItem.isValid()) { result.append(relationItem); } } return true; } QJsonArray MonitorPanel::serializeParaToJsonArray(const QMap>& data) const { QJsonArray rootArray; for (auto it = data.begin(); it != data.end(); ++it) { const QUuid& uuid = it.key(); const QList& attributeList = it.value(); QJsonObject uuidObject; uuidObject["uuid"] = uuid.toString(); QJsonArray attributesArray; // 序列化属性列表 for (const auto& attribute : attributeList) { attributesArray.append(attribute.toJson()); } uuidObject["attributes"] = attributesArray; uuidObject["attributeCount"] = attributesArray.size(); rootArray.append(uuidObject); } return rootArray; } // 从 QJsonArray 反序列化到 QMap> bool MonitorPanel::deserializeParaFromJsonArray(const QJsonArray& jsonArray, QMap>& result) { result.clear(); for (const QJsonValue& uuidValue : jsonArray) { if (!uuidValue.isObject()) continue; QJsonObject uuidObject = uuidValue.toObject(); // 解析UUID QUuid uuid = QUuid::fromString(uuidObject["uuid"].toString()); if (uuid.isNull()) continue; // 解析属性列表 QList attributeList; QJsonArray attributesArray = uuidObject["attributes"].toArray(); for (const QJsonValue& attrValue : attributesArray) { if (!attrValue.isObject()) continue; monitorItemAttributeInfo attribute; attribute.fromJson(attrValue.toObject()); attributeList.append(attribute); } result[uuid] = attributeList; } return true; } QJsonArray MonitorPanel::serializeDisplayToJsonArray(const QMap>& data) const { QJsonArray rootArray; for (auto typeIt = data.begin(); typeIt != data.end(); ++typeIt) { const monitorItemTypeStruct& typeKey = typeIt.key(); const auto& stateMap = typeIt.value(); QJsonObject typeObject; typeObject["typeKey"] = typeKey.toJson(); QJsonArray statesArray; for (auto stateIt = stateMap.begin(); stateIt != stateMap.end(); ++stateIt) { const monitorItemStateStruct& stateKey = stateIt.key(); const monitorItemDisplayInfo& displayInfo = stateIt.value(); QJsonObject stateObject; stateObject["stateKey"] = stateKey.toJson(); stateObject["displayInfo"] = displayInfo.toJson(); statesArray.append(stateObject); } typeObject["states"] = statesArray; rootArray.append(typeObject); } return rootArray; } // 从JSON数组反序列化 void MonitorPanel::deserializeDisplayFromJsonArray(const QJsonArray& jsonArray,QMap>& result) { result.clear(); for (const QJsonValue& typeValue : jsonArray) { if (!typeValue.isObject()) continue; QJsonObject typeObject = typeValue.toObject(); // 解析类型键 monitorItemTypeStruct typeKey; typeKey.fromJson(typeObject["typeKey"].toObject()); QMap stateMap; QJsonArray statesArray = typeObject["states"].toArray(); for (const QJsonValue& stateValue : statesArray) { if (!stateValue.isObject()) continue; QJsonObject stateObject = stateValue.toObject(); monitorItemStateStruct stateKey; stateKey.fromJson(stateObject["stateKey"].toObject()); monitorItemDisplayInfo displayInfo; displayInfo.fromJson(stateObject["displayInfo"].toObject()); stateMap[stateKey] = displayInfo; } result[typeKey] = stateMap; } }