fixed project model default value

This commit is contained in:
baiYue 2025-05-09 19:36:32 +08:00
parent 014051e9c4
commit 267026ddc4
26 changed files with 646 additions and 142 deletions

View File

@ -49,6 +49,8 @@ set(H_HEADER_FILES
include/projectTableDelegate.h
include/selectorDialog.h
include/topologyView.h
include/diagramView.h
include/topologyTree.h
common/include/global.h
common/include/tools.h
@ -73,6 +75,8 @@ set(CPP_SOURCE_FILES
source/projectTableDelegate.cpp
source/selectorDialog.cpp
source/topologyView.cpp
source/diagramView.cpp
source/topologyTree.cpp
common/source/httpInterface.cpp
common/source/global.cpp
@ -84,6 +88,7 @@ set(UI_FILES
ui/loadPageDlg.ui
ui/projectModelDlg.ui
ui/topologyView.ui
ui/diagramView.ui
)
#

View File

@ -264,9 +264,7 @@ enum class EntityType {
Zone,
Station,
ConfigurationDiagram,
Transformer,
BusBar,
CircuitBreaker };
Component };
struct EntityInfo
{
@ -276,7 +274,15 @@ struct EntityInfo
EntityType eType;
};
struct DiagramView {
struct DiagramInfo //组态图结构信息
{
QVariant id; //临时id使用uuidload数据使用数据库自增id
QString sName;
QString sTag;
QVariant parentId;
};
struct DiagramContent {
QString diagramId; // 对应的PowerEntity ID
// 元素位置信息 <元素ID, 位置>

View File

@ -38,6 +38,9 @@ protected:
void keyPressEvent(QKeyEvent*) override;
void keyReleaseEvent(QKeyEvent*) override;
void contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent) override;
void dragEnterEvent(QGraphicsSceneDragDropEvent *event) override;
void dragMoveEvent(QGraphicsSceneDragDropEvent *event) override;
void dropEvent(QGraphicsSceneDragDropEvent *event) override;
private:
bool m_bGridVisible;
QGraphicsView* m_pView;

View File

@ -39,6 +39,11 @@ public slots:
void onSignal_changeEntity(EntityInfo);
void onSignal_deleteEntity(EntityInfo);
void onSignal_selectEntity(EntityInfo);
void onSignal_createDiagram(DiagramInfo);
void onSignal_changeDiagram(DiagramInfo);
void onSignal_deleteDiagram(DiagramInfo);
void onSignal_selectDiagram(DiagramInfo);
private:
void removePanel(PowerEntity*);
private:

View File

@ -48,6 +48,8 @@ public:
void initialPropertyDlg(); //初始化属性设置dlg每个模型拥各自的dlg
void generatePropertyDlg(const QString&);
ConfigurationDiagram* getTopologyDiagram(); //返回当前组态图的拓扑实体
void createTopoTerminals(GraphicsBaseItem*);
bool isItemValid(GraphicsBaseItem*); //判断item是否可以连接
Q_SIGNALS:
void activatePage(const QString&); //激活当前model所在page
public:
@ -75,6 +77,5 @@ private:
QMap<QString,modelDataInfo> _modelDataInfo; //模型数据信息
public:
static bool _dataInitialised;
static QMap<QUuid,BaseProperty*> _nodeData; //一个data可对应多个item
};

View File

@ -10,6 +10,7 @@
#include "global.h"
class PowerEntity;
class BaseProperty;
class TopologyManager : public QObject {
Q_OBJECT
@ -21,10 +22,6 @@ public:
PowerEntity* findEntity(const QString& id) const;
bool deleteEntity(const QString& id);
// 序列化
QJsonObject serialize() const;
void deserialize(const QJsonObject& json);
// 连接管理
PowerConnection* createConnection(const QString& uuid,const QString& fromId, const QString& toId);
QList<PowerConnection*> getConnectionsForTerminal(const QString& terminalId) const;
@ -43,6 +40,16 @@ public:
PowerEntity* getEntity(const QString& id) const;
QList<PowerEntity*> findEntitiesByName(const QString& name) const;
//==========================组态图拓扑相关===================================
PowerEntity* createDiagram(const QString& id,const QString& name); //单独创建组态图
PowerEntity* findDiagram(const QString& id) const;
bool deleteDiagram(const QString& id);
//===========================元件实时数据================================
void insertEntityData(QUuid,BaseProperty*);
BaseProperty* findEntityData(QUuid);
void deleteEntityData(QUuid);
QMap<QUuid,BaseProperty*> getEntityData() const;
public:
// 接线点管理
PowerTerminal* createTerminal(const QString& parentEntityId,
@ -66,11 +73,14 @@ private:
~TopologyManager();
void clearAllData();
QHash<QString, PowerEntity*> m_entities; // ID到实体映射
QHash<QString, DiagramView*> m_views; // 组态图视图存储
QHash<QString, DiagramContent*> m_views; // 组态图视图存储
QHash<QString, PowerEntity*> m_diagrams; // 组态图拓扑结构
// 连接存储
QHash<QString,PowerConnection*> m_connections;
QMultiHash<QString,PowerConnection*> m_connectionIndex; // 接线点ID到连接的映射
QMap<QUuid,BaseProperty*> m_entityData; //每个实例化元件的唯一数据
private:
QHash<QString, PowerTerminal*> m_allTerminals; // ID到接线点映射
QHash<QString, QList<PowerTerminal*>> m_terminalsByEntity; // 实体ID到接线点列表

View File

@ -55,6 +55,9 @@ public:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*);
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*);
virtual void dropEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*);
SelectorType getSelectorType() { return m_type; }
//void setOperationMode(OperationMode m) { m_opMode = m; }
@ -65,7 +68,6 @@ public:
QString sceneName() const {return m_sceneName;}
FixedPortsModel* getModel() {return _model;}
void createTopoTerminals(GraphicsBaseItem*);
void updateConnectLineByTopology(QList<QGraphicsItem *>); //通过拓扑关系更新位置
signals:
void setWorkingSelector(SelectorType);

View File

@ -34,7 +34,6 @@ DesignerScene::DesignerScene(FixedPortsModel* graphModel, QObject *parent)
m_bGridVisible = true;
m_pView = nullptr;
m_pDrawingPanel = dynamic_cast<DrawingPanel*>(parent);
}
DesignerScene::~DesignerScene()
{
@ -146,6 +145,45 @@ void DesignerScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenu
}
}
void DesignerScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
if(m_pDrawingPanel)
{
if(m_pDrawingPanel->getMode() == DM_run)
return;
m_pDrawingPanel->selectorManager()->getWorkingSelector()->dragEnterEvent(event, this);
update();
}
else
QGraphicsScene::dragEnterEvent(event);
}
void DesignerScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
if(m_pDrawingPanel)
{
if(m_pDrawingPanel->getMode() == DM_run)
return;
m_pDrawingPanel->selectorManager()->getWorkingSelector()->dragMoveEvent(event, this);
update();
}
else
QGraphicsScene::dragMoveEvent(event);
}
void DesignerScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
if(m_pDrawingPanel)
{
if(m_pDrawingPanel->getMode() == DM_run)
return;
m_pDrawingPanel->selectorManager()->getWorkingSelector()->dropEvent(event, this);
update();
}
else
QGraphicsScene::dropEvent(event);
}
void DesignerScene::onDeleteClicked()
{
QList<QGraphicsItem*> listItem = selectedItems();

View File

@ -161,13 +161,7 @@ void DiagramCavas::onSignal_panelDelete(const QString& name)
DrawingPanel* pPanel = m_mapDrawPanel.take(name).first;
if(m_mapDrawPanel.isEmpty())
{
/*for(auto it = FixedPortsModel::_nodeData.begin();it!=FixedPortsModel::_nodeData.end();)
{
it = FixedPortsModel::_nodeData.erase(it);
}*/
qDeleteAll(FixedPortsModel::_nodeData);
FixedPortsModel::_nodeData.clear();
FixedPortsModel::_dataInitialised = false;
//FixedPortsModel::_dataInitialised = false;
}
this->removeSubWindow(pPanel);
delete pPanel;
@ -232,25 +226,64 @@ void DiagramCavas::onSignal_selectEntity(EntityInfo info)
PowerEntity* pEntity = TopologyManager::instance().findEntity(info.sUuid);
if(pEntity)
{
if(info.eType == EntityType::ConfigurationDiagram)
{
PowerEntity* pEntity = TopologyManager::instance().findEntity(info.sUuid);
if(pEntity)
{
switch (info.eType){
case EntityType::Grid:
case EntityType::Zone:
case EntityType::Station:
break;
case EntityType::ConfigurationDiagram:
onSignal_loadPage(pEntity);
break;
default:
break;
}
}
switch (info.eType){
case EntityType::Grid:
case EntityType::Zone:
case EntityType::Station:
break;
default:
break;
}
}
else //不存在,从数据库中load
{
}
}
void DiagramCavas::onSignal_createDiagram(DiagramInfo info)
{
PowerEntity* pEntity;
pEntity = TopologyManager::instance().findDiagram(info.id.toString());
if(!pEntity) //不存在创建
{
pEntity = TopologyManager::instance().createDiagram(info.id.toString(),info.sName);
PowerEntity* pParent = TopologyManager::instance().findDiagram(info.parentId.toString());
if(pParent) //构建父子关系
{
pParent->addChild(pEntity);
}
onSignal_addDrawingPanel(pEntity);
}
}
void DiagramCavas::onSignal_changeDiagram(DiagramInfo info)
{
}
void DiagramCavas::onSignal_deleteDiagram(DiagramInfo info)
{
PowerEntity* pEntity = TopologyManager::instance().findDiagram(info.id.toString());
if(pEntity)
{
removePanel(pEntity);
TopologyManager::instance().deleteEntity(info.id.toString());
}
}
void DiagramCavas::onSignal_selectDiagram(DiagramInfo info)
{
PowerEntity* pEntity = TopologyManager::instance().findDiagram(info.id.toString());
if(pEntity)
{
onSignal_loadPage(pEntity);
}
else //不存在,从数据库中load
{
}
}
void DiagramCavas::removePanel(PowerEntity* pEntity)

View File

@ -16,7 +16,6 @@
#include <QJsonArray>
#include <QMessageBox>
QMap<QUuid,BaseProperty*> FixedPortsModel::_nodeData;
bool FixedPortsModel::_dataInitialised = false;
FixedPortsModel::FixedPortsModel(PowerEntity* pEntity)
@ -91,9 +90,10 @@ void FixedPortsModel::addNodeItem(QUuid id/*,int type*/,QPointF pos)
{
BaseProperty* pro = nullptr;
GraphicsBaseItem* item = nullptr;
if(_nodeData.contains(id))
QMap<QUuid,BaseProperty*> mapData = TopologyManager::instance().getEntityData();
if(mapData.contains(id))
{
pro = _nodeData[id];
pro = mapData[id];
if(pro)
{
int type = pro->type();
@ -142,8 +142,9 @@ void FixedPortsModel::addNodeItem(QUuid id/*,int type*/,QPointF pos)
BaseProperty* FixedPortsModel::addNodeData(QUuid id,int type,QString name,QString modelName)
{
if(_nodeData.contains(id))
return nullptr;
BaseProperty* pData = TopologyManager::instance().findEntityData(id); //已存在不不创建
if(pData != nullptr)
return pData;
VariableProperty* item = new VariableProperty(this);
//todo:关联到对应data
@ -155,7 +156,7 @@ BaseProperty* FixedPortsModel::addNodeData(QUuid id,int type,QString name,QStrin
item->setType(type);
item->setTag(name);
item->setName(name);
_nodeData.insert(id,item);
TopologyManager::instance().insertEntityData(id,item);
}
return item;
}
@ -205,7 +206,7 @@ void FixedPortsModel::loadNodeDataFromDataBase()
}
else
{
for(auto p:_nodeData)
//for(auto p:_nodeData)
{
int a = 1;
}
@ -453,7 +454,8 @@ QJsonObject FixedPortsModel::saveNode(QUuid const nodeId) const
void FixedPortsModel::saveNode(int nPageId)
{
for(auto &pData:_nodeData)
QMap<QUuid,BaseProperty*> mapData = TopologyManager::instance().getEntityData();
for(auto &pData:mapData)
{
if(pData->prepareDelete())
{
@ -494,7 +496,8 @@ void FixedPortsModel::onSignal_ifExits(QUuid id,const QString& str,int type,Grap
{
bool exist = false;
BaseProperty* pData = nullptr;
for(auto pro:_nodeData)
QMap<QUuid,BaseProperty*> mapData = TopologyManager::instance().getEntityData();
for(auto pro:mapData)
{
if(pro->tag() == str)
{
@ -509,7 +512,7 @@ void FixedPortsModel::onSignal_ifExits(QUuid id,const QString& str,int type,Grap
return;
QMessageBox msgBox;
msgBox.setText(QString::fromWCharArray(L"提示"));
msgBox.setInformativeText(QString::fromWCharArray(L"此名称模型已存在,是否替换?"));
msgBox.setInformativeText(QString::fromWCharArray(L"此名称对象已存在,是否使用该对象?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
@ -519,6 +522,10 @@ void FixedPortsModel::onSignal_ifExits(QUuid id,const QString& str,int type,Grap
//todo:断开原来的连接关系
pitem->setProperty(pData);
pitem->setItemId(pData->uuid());
PowerEntity* pEntity = TopologyManager::instance().findEntity(pData->uuid().toString());
if(pEntity){
pitem->setEntity(pEntity); //item对象的逻辑接线点无需重复创建
}
_nodeItem.take(id);
_nodeItem.insert(pData->uuid(),pitem);
}
@ -533,12 +540,17 @@ void FixedPortsModel::onSignal_ifExits(QUuid id,const QString& str,int type,Grap
}
else //创建新data并绑定
{
BaseProperty* pItem = addNodeData(id,type,str,pitem->getModelName());
if(pItem)
BaseProperty* pData = addNodeData(id,type,str,pitem->getModelName());
if(pData)
{
pitem->setProperty(pItem);
pItem->setDataChanged(true); //数据状态改变
pitem->setProperty(pData);
pData->setDataChanged(true); //数据状态改变
}
PowerEntity* pEntity = TopologyManager::instance().createEntity(EntityType::Component,id.toString(),str);
if(pEntity)
pitem->setEntity(pEntity);
createTopoTerminals(pitem); //创建item对象的逻辑接线点
}
}
@ -555,10 +567,10 @@ void FixedPortsModel::onSignal_GetPointData(QString type,QMap<qint64,double> map
{
double d = map.first();
for(auto pro:_nodeData) //demo版本只有一个数据
//for(auto pro:_nodeData) //demo版本只有一个数据
{
int t = pro->type();
if(t == GIT_itemRect)
//int t = pro->type();
//if(t == GIT_itemRect)
{
//todo:根据id匹配数据
/*auto p = dynamic_cast<ElectricSvgItemRect_Property*>(pro);
@ -670,3 +682,40 @@ ConfigurationDiagram* FixedPortsModel::getTopologyDiagram()
{
return dynamic_cast<ConfigurationDiagram*>(_pEntity);
}
void FixedPortsModel::createTopoTerminals(GraphicsBaseItem* pItem)
{
PowerEntity* pEntity = pItem->entity();
if(pEntity)
{
QMap<QString,ItemPort*> mapPorts = pItem->getPorts(); //创建对应
for(auto &port:mapPorts)
{
TerminalType terType;
HandleType tpe = port->getType();
switch (tpe) {
case T_lineIn:
terType = TerminalType::PowerInput;
break;
case T_lineOut:
terType = TerminalType::PowerOutput;
break;
case T_lineInOut:
terType = TerminalType::PowerConnect;
break;
default:
break;
}
TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId());
}
}
}
bool FixedPortsModel::isItemValid(GraphicsBaseItem* pItem)
{
BaseProperty* pData = pItem->getProperty();
PowerEntity* pEntity = pItem->entity();
return (pData != nullptr && pEntity != nullptr)?true:false;
}

View File

@ -92,7 +92,11 @@ void ItemPropertyDlg::onGroupSelected(const QString& str)
PropertyContentDlg* pDlg = qobject_cast<PropertyContentDlg*>(groupViews_[str]);
if(pDlg)
{
QMap<QString,propertyStateInfo> valueMap = groupValue_[str].mapInfo[curUuid_];
QMap<QString,propertyStateInfo> valueMap;
if(groupValue_[str].mapInfo.contains(curUuid_))
valueMap = groupValue_[str].mapInfo[curUuid_];
else //没有值时使用默认值
valueMap = groupInfo_[str].info;
pDlg->setPropertyValue(valueMap);
}

View File

@ -2,6 +2,7 @@
#include <QJsonDocument>
#include "topologyManager.h"
#include "powerEntity.h"
#include "graphicsItem/graphicsBaseItem.h"
TopologyManager& TopologyManager::instance()
{
@ -28,6 +29,8 @@ void TopologyManager::clearAllData()
m_entities.clear();
m_allTerminals.clear(); //端点由父亲entity释放
m_entityData.clear(); //data数据由系统自动释放
}
PowerEntity* TopologyManager::createEntity(EntityType type,const QString& uuid, const QString& name)
@ -317,6 +320,69 @@ QList<PowerEntity*> TopologyManager::findEntitiesByName(const QString& name) con
return results;
}
PowerEntity* TopologyManager::createDiagram(const QString& id,const QString& name)
{
PowerEntity* entity = nullptr;
entity = new ConfigurationDiagram(id,name);
m_diagrams.insert(entity->id(), entity);
return entity;
}
PowerEntity* TopologyManager::findDiagram(const QString& id) const
{
return m_diagrams.value(id, nullptr); // 避免异常的安全查询
}
bool TopologyManager::deleteDiagram(const QString& id)
{
if (!m_diagrams.contains(id)) return false;
PowerEntity* entity = m_diagrams[id];
// 步骤2从父节点移除防止悬空指针
if (PowerEntity* parent = entity->parent()) {
parent->removeChild(entity);
}
// 步骤3递归删除子实体
auto children = entity->children();
for (auto child : children) {
deleteDiagram(child->id()); // 递归删除
}
// 步骤4从哈希表移除并释放内存
m_diagrams.remove(id);
delete entity; // 触发析构函数
return true;
}
void TopologyManager::insertEntityData(QUuid uid,BaseProperty* p)
{
if(!m_entityData.contains(uid))
m_entityData.insert(uid,p);
}
BaseProperty* TopologyManager::findEntityData(QUuid uid)
{
return m_entityData.value(uid,nullptr);
}
void TopologyManager::deleteEntityData(QUuid uid)
{
BaseProperty* pData = m_entityData.value(uid,nullptr);
if(pData)
delete pData;
}
QMap<QUuid,BaseProperty*> TopologyManager::getEntityData() const
{
return m_entityData;
}
PowerTerminal* TopologyManager::createTerminal(const QString& parentEntityId,
TerminalType type,
const QString& name,

View File

@ -2,6 +2,7 @@
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QDebug>
#include <QMimeData>
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/handleText.h"
#include "powerEntity.h"
@ -382,6 +383,33 @@ void BaseSelector::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, Design
}
}
void BaseSelector::dragEnterEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*)
{
if (event->mimeData()->hasText()) {
event->acceptProposedAction();
}
}
void BaseSelector::dragMoveEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*)
{
if (event->mimeData()->hasText()) {
event->acceptProposedAction();
}
}
void BaseSelector::dropEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*)
{
if (event->mimeData()->hasText()) {
QString text = event->mimeData()->text();
// 根据拖拽的数据创建相应的图形项并添加到场景中
// 例如创建一个文本项
QGraphicsTextItem *textItem = new QGraphicsTextItem(text);
textItem->setPos(event->scenePos());
//addItem(textItem);
event->acceptProposedAction();
}
}
void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
{
QGraphicsView *view = scene->getView();
@ -389,36 +417,6 @@ void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
view->setCursor(cursor);
}
void BaseSelector::createTopoTerminals(GraphicsBaseItem* pItem)
{
PowerEntity* pEntity = pItem->entity();
if(pEntity)
{
QMap<QString,ItemPort*> mapPorts = pItem->getPorts(); //创建对应
for(auto &port:mapPorts)
{
TerminalType terType;
HandleType tpe = port->getType();
switch (tpe) {
case T_lineIn:
terType = TerminalType::PowerInput;
break;
case T_lineOut:
terType = TerminalType::PowerOutput;
break;
case T_lineInOut:
terType = TerminalType::PowerConnect;
break;
default:
break;
}
TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId());
}
}
}
void BaseSelector::updateConnectLineByTopology(QList<QGraphicsItem *> lst)
{
for(auto iter:lst) //更新连接线

View File

@ -6,6 +6,7 @@
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
#include <QMessageBox>
ConnectingSelector::ConnectingSelector(FixedPortsModel* model,QObject *parent)
: BaseSelector(model,parent)
@ -89,6 +90,10 @@ void ConnectingSelector::setTargetHighLight(bool val)
void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,GraphicsBaseItem* touchedItem,DesignerScene* scene)
{
if (!_model->isItemValid(connectingItem) || !_model->isItemValid(touchedItem)) {
QMessageBox::information(NULL, QString("提示"), QString::fromWCharArray(L"请先完成设备命名"));
return;
}
QUuid uid = QUuid::createUuid();
ElectricConnectLineItem* pItem = new ElectricConnectLineItem();
pItem->setItemId(uid);
@ -96,10 +101,7 @@ void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,Gra
scene->addItem(pItem);
ItemPort* ptSrc = connectingItem->getPortPtr(ms_nDragHandle);
//QUuid srcId = connectingItem->itemId();
//int srcPort = ptSrc->getTag();
//HandleType srcType = ptSrc->getType();
//PortPos srcPos = ptSrc->portPos();
pItem->setStartPoint(ptSrc->scenePos());
ptSrc->setConnect(pItem);
QString srcPortId = ptSrc->getId(); //port自身id
@ -114,7 +116,7 @@ void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,Gra
pItem->setEndPoint(ptDest->scenePos());
}
createTopoTerminals(touchedItem); //创建port时创建对应的terminal
_model->createTopoTerminals(touchedItem); //创建port时创建对应的terminal
}
else
{
@ -125,16 +127,8 @@ void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,Gra
if(ptDest != nullptr)
{
//QUuid destId = touchedItem->itemId();
//int destPort = ptDest->getTag();
//HandleType destType = ptDest->getType();
//PortPos destPos = ptDest->portPos();
QString destPortId = ptDest->getId(); //port自身id
//pItem->calculatePath();
//pItem->setConnection(Connection(srcId,srcPort,srcType,srcPos,destId,destPort,destType,destPos));
//ptDest->setConnect(pItem);
if(TopologyManager::instance().validateConnection(srcPortId,destPortId))
TopologyManager::instance().createConnection(uid.toString(),srcPortId,destPortId); //创建拓扑连接(逻辑)

View File

@ -34,7 +34,6 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
ms_ptMouseLast = event->scenePos();
QUuid uuid = QUuid::createUuid();
EntityInfo info;
if(m_pCreatingItem == nullptr)
{
scene->clearSelection();
@ -67,7 +66,6 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
m_pCreatingItem->setItemType(GIT_bus);
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
emit setWorkingSelector(ST_base);
info.eType = EntityType::BusBar;
}
break;
case GIT_itemRect:
@ -78,7 +76,6 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
m_pCreatingItem->setItemType(GIT_itemRect);
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
emit setWorkingSelector(ST_base);
info.eType = EntityType::CircuitBreaker;
}
break;
case GIT_itemTri:
@ -114,13 +111,6 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
qDebug()<<"item type error";
return;
}
info.sUuid = uuid.toString();
PowerEntity* pEntity = TopologyManager::instance().createEntity(info.eType,info.sUuid,info.sName);
if(pEntity)
m_pCreatingItem->setEntity(pEntity);
createTopoTerminals(m_pCreatingItem);
}
if(m_pCreatingItem && m_creatingMethod == CM_click)

36
include/diagramView.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef DIAGRAMVIEW_H
#define DIAGRAMVIEW_H
#include <QDialog>
#include <QStandardItemModel>
#include "global.h"
QT_BEGIN_NAMESPACE
namespace Ui { class diagramView; }
QT_END_NAMESPACE
class DiagramView : public QDialog
{
Q_OBJECT
public:
DiagramView(QWidget *parent = nullptr);
~DiagramView();
void initial();
void loadTopologyFromDB(); //加载拓扑关系
signals:
void diagramCreate(DiagramInfo);
void diagramChange(DiagramInfo);
void diagramDelete(DiagramInfo);
void diagramSelected(DiagramInfo);
public slots:
void onIndexRbtnClicked(const QPoint &pos); //索引列表右键菜单
void onItemChanged(QStandardItem *item);
void onItemClicked(const QModelIndex &index);
private:
Ui::diagramView *ui;
QStandardItemModel* _pModel;
};
#endif

View File

@ -20,6 +20,7 @@ class ElectricElementsBox;
class LoadPageDlg;
class projectModelDlg;
class TopologyView;
class DiagramView;
class CMainWindow : public QMainWindow
{
@ -68,6 +69,7 @@ private:
DrawingPanel* m_pDrawingPanel;
ElectricElementsBox* m_pElectricElementsBox;
TopologyView* m_pTopologyView;
DiagramView* m_pDiagramView;
GraphicElementsPanel* m_pGraphicElementsPanel;
LoadPageDlg* m_pLoadPageDlg;
projectModelDlg* m_pProjectModelDlg;

17
include/topologyTree.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef TOPOLOGYTREE_H
#define TOPOLOGYTREE_H
#include <QTreeView>
/***************拖拽实现*************/
class TopologyTree : public QTreeView
{
Q_OBJECT
public:
TopologyTree(QWidget *parent = nullptr);
~TopologyTree();
protected:
void mouseMoveEvent(QMouseEvent *event) override;
};
#endif

View File

@ -9,6 +9,7 @@ QT_BEGIN_NAMESPACE
namespace Ui { class topologyView; }
QT_END_NAMESPACE
class TopologyTree;
class TopologyView : public QDialog
{
@ -19,6 +20,7 @@ public:
~TopologyView();
void initial();
void loadTopologyFromDB(); //加载拓扑关系
signals:
void entityCreate(EntityInfo);
void entityChange(EntityInfo);
@ -31,6 +33,7 @@ public slots:
private:
Ui::topologyView *ui;
QStandardItemModel* _pModel;
TopologyTree* _treeView;
};
#endif

155
source/diagramView.cpp Normal file
View File

@ -0,0 +1,155 @@
#include "diagramView.h"
#include "ui_diagramView.h"
#include "tools.h"
#include <QStandardItemModel>
#include <QMenu>
#include <QUuid>
DiagramView::DiagramView(QWidget *parent)
: QDialog(parent)
, ui(new Ui::diagramView)
,_pModel(nullptr)
{
ui->setupUi(this);
_pModel = new QStandardItemModel(this);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
}
DiagramView::~DiagramView()
{
delete ui;
}
void DiagramView::initial()
{
connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &DiagramView::onIndexRbtnClicked);
connect(ui->treeView, &QTreeView::clicked, this, &DiagramView::onItemClicked);
connect(_pModel, &QStandardItemModel::itemChanged, this, &DiagramView::onItemChanged);
ui->treeView->setHeaderHidden(true);
// 设置模型的列数
_pModel->setColumnCount(1);
// 创建树视图
ui->treeView->setModel(_pModel);
// 展开所有节点
ui->treeView->expandAll();
// 显示树视图
ui->treeView->setWindowTitle(QObject::tr("组态图结构"));
}
void DiagramView::loadTopologyFromDB()
{
}
void DiagramView::onIndexRbtnClicked(const QPoint &pos)
{
// 获取当前点击的位置对应的索引
QMenu menu;
QModelIndex index = ui->treeView->indexAt(pos);
if (!index.isValid()) {
// 如果点击的是空白区域,创建新组态图菜单
int nCount = _pModel->invisibleRootItem()->rowCount();
QAction *addAction = new QAction("添加组态图", this);
connect(addAction,&QAction::triggered,this,[&](){
QVariant id = QUuid::createUuid();
QString sName = QString::fromWCharArray(L"组态图_")+QString::number(nCount);
QStandardItem *gridItem = new QStandardItem(sName);
gridItem->setData(id,Qt::UserRole+1);
_pModel->appendRow(gridItem);
DiagramInfo info;
//todo:具体信息
info.id = id; //新建的组态图随机赋予临时id
info.sName = sName;
info.sTag = sName;
emit diagramCreate(info);
});
menu.addAction(addAction);
}
else{ //目标组态图下添加子组态图
QStandardItem* item = _pModel->itemFromIndex(index);
QVariant parentId = item->data(Qt::UserRole+1);
if(item)
{
int nCount = item->rowCount();
QAction *addAction = new QAction("添加子组态图", this);
connect(addAction,&QAction::triggered,this,[&](){
QVariant id = QUuid::createUuid();
QString sName = item->text()+"_"+QString::number(nCount);
QStandardItem *gridItem = new QStandardItem(sName);
gridItem->setData(id,Qt::UserRole+1);
item->appendRow(gridItem);
DiagramInfo info;
//todo:具体信息
info.id = id; //新建的随机赋予临时id
info.sName = sName;
info.sTag = sName;
info.parentId = parentId;
emit diagramCreate(info);
});
menu.addAction(addAction);
QAction *delAction = new QAction("删除", this);
connect(delAction,&QAction::triggered,this,[&](){
QModelIndex currentIndex = ui->treeView->currentIndex();
if(currentIndex.isValid())
{
QStandardItem* pItem = _pModel->itemFromIndex(currentIndex);
QVariant id = pItem->data(Qt::UserRole+1);
QString sName = pItem->text();
if(pItem)
{
QString str = item->text();
DiagramInfo info;
//todo:具体信息
info.id = id; //新建的随机赋予临时id
info.sName = sName;
info.sTag = sName;
info.parentId = parentId;
emit diagramDelete(info);
QStandardItem* pParent = item->parent();
if(pParent)
{
pParent->removeRow(currentIndex.row());
}
}
}
});
menu.addAction(delAction);
}
}
// 在点击位置显示菜单
menu.exec(ui->treeView->mapToGlobal(pos));
}
void DiagramView::onItemChanged(QStandardItem *item)
{
int nLevel = getLevel(item);
QString str = item->text();
DiagramInfo info;
//todo:具体信息
emit diagramChange(info);
}
void DiagramView::onItemClicked(const QModelIndex &index)
{
QStandardItem* item = _pModel->itemFromIndex(index);
if(item)
{
DiagramInfo info;
//todo:具体信息
emit diagramSelected(info);
}
}

View File

@ -13,6 +13,7 @@
#include <QDebug>
#include <QSqlDatabase>
#include <QMessageBox>
#include <QVBoxLayout>
#include "diagramCavas.h"
#include "designerScene.h"
@ -24,6 +25,7 @@
#include "loadPageDlg.h"
#include "projectModelDlg.h"
#include "topologyView.h"
#include "diagramView.h"
//using namespace ads;
@ -36,6 +38,7 @@ CMainWindow::CMainWindow(QWidget *parent)
m_pUndoStack = nullptr;
m_pLoadPageDlg = nullptr;
m_pTopologyView = nullptr;
m_pDiagramView = nullptr;
initializeDockUi();
initializeAction();
@ -78,10 +81,17 @@ void CMainWindow::initializeDockUi()
m_pTopologyView->initial();
QDockWidget* topologyDock = new QDockWidget(QString::fromWCharArray(L"拓扑关系"),this);
topologyDock->setWidget(m_pTopologyView);
topologyDock->setMinimumSize(120,550);
//topologyDock->setMinimumSize(120,550);
topologyDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::LeftDockWidgetArea,topologyDock);
m_pDiagramView = new DiagramView(this);
m_pDiagramView->initial();
QDockWidget* diagramDock = new QDockWidget(QString::fromWCharArray(L"组态图列表"),this);
diagramDock->setWidget(m_pDiagramView);
diagramDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::LeftDockWidgetArea,diagramDock);
m_pDiagramCavas = new DiagramCavas();
m_pDiagramCavas->initial();
this->setCentralWidget(m_pDiagramCavas);
@ -120,6 +130,11 @@ void CMainWindow::initializeAction()
connect(m_pTopologyView,&TopologyView::entityDelete,m_pDiagramCavas,&DiagramCavas::onSignal_deleteEntity);
connect(m_pTopologyView,&TopologyView::entitySelected,m_pDiagramCavas,&DiagramCavas::onSignal_selectEntity);
connect(m_pDiagramView,&DiagramView::diagramCreate,m_pDiagramCavas,&DiagramCavas::onSignal_createDiagram);
connect(m_pDiagramView,&DiagramView::diagramChange,m_pDiagramCavas,&DiagramCavas::onSignal_changeDiagram);
connect(m_pDiagramView,&DiagramView::diagramDelete,m_pDiagramCavas,&DiagramCavas::onSignal_deleteDiagram);
connect(m_pDiagramView,&DiagramView::diagramSelected,m_pDiagramCavas,&DiagramCavas::onSignal_selectDiagram);
connect(ui->actionNew,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_addPage);
connect(ui->actionOpen,&QAction::triggered,this,&CMainWindow::onSignal_loadPage);
connect(ui->actionSave,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_savePage);

View File

@ -9,7 +9,7 @@
#include "projectTableDelegate.h"
#include "logger.h"
const QSet<QString> stringDataTypes = {"varchar", "char", "text", "date", "time", "timestamp"};
const QSet<QString> stringDataTypes = {"VARCHAR", "CHAR", "TEXT", "DATE", "TIME", "TIMESTAMP","JSONB","JSON"};
projectModelDlg::projectModelDlg(QWidget *parent)
: QDialog(parent)
@ -62,6 +62,7 @@ MapProperty projectModelDlg::addNewProject(const QString& sMeta,const QString& s
for(auto &property:lstProperty)
{
PropertyPage struProperty;
struProperty.isPublic = false;
if(mapCheckState.contains(property) && !model.formerMeta.bChanged) //生成的模型中勾选了该属性组且元模未改变过
{
@ -171,6 +172,8 @@ MapProperty projectModelDlg::addNewProject(const QString& sMeta,const QString& s
}
for (auto it = mt.begin(); it != mt.end(); ++it) { //将正常属性添到公共属性后
if(pubMap.contains(it.key()))
continue; //公共属性组已有的不重复添加
pubMap.insert(it.key(), it.value());
}
@ -1316,13 +1319,13 @@ QPair<QString,QString> projectModelDlg::combinePropertySql(const QStandardItem*
QString sql = QString("%1 %2").arg(attribute, dataTypePart);
// 处理约束条件
if (isNotNull != 0) {
if (isNotNull != -1) {
sql += " NOT NULL";
}
if (!defaultValue.isEmpty()) {
QString defValue = defaultValue;
if (needsQuotes) {
if (needsQuotes && defValue != "null" && defValue != "NULL") {
// 转义单引号并包裹
defValue.replace("'", "''");
defValue = QString("'%1'").arg(defValue);
@ -1583,6 +1586,9 @@ int projectModelDlg::createPropertyTable(const QString& sProject,const QString&
for(auto &item:lstSelect)
{
QString attribute = item->data(Attribute).toString();
if(attribute.contains("global_uuid"))
continue;
QPair<QString,QString> pair = combinePropertySql(item); //拼接单句sql
fields.append(pair.first);
}

44
source/topologyTree.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <QMouseEvent>
#include <QMimeData>
#include <QDrag>
#include <QPainter>
#include "topologyTree.h"
#include "global.h"
TopologyTree::TopologyTree(QWidget *parent)
: QTreeView(parent)
{
}
TopologyTree::~TopologyTree()
{
}
void TopologyTree::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
// 创建QMimeData并将选中项的文本放入
QMimeData *mimeData = new QMimeData();
mimeData->setText(model()->data(index, Qt::DisplayRole).toString());
// 创建拖拽对象
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
// 设置拖拽的图标(这里用一个简单的图标,也可以使用其他方式)
QPixmap pixmap(100, 30);
pixmap.fill(Qt::white);
QPainter painter(&pixmap);
painter.drawText(0, 20, model()->data(index, Qt::DisplayRole).toString());
drag->setPixmap(pixmap);
drag->setHotSpot(event->pos() - rect().topLeft());
// 启动拖拽操作
drag->exec(Qt::CopyAction);
}
}
}

View File

@ -1,20 +1,24 @@
#include "topologyView.h"
#include "ui_topologyView.h"
#include "tools.h"
#include "topologyTree.h"
#include <QStandardItemModel>
#include <QMenu>
#include <QUuid>
TopologyView::TopologyView(QWidget *parent)
: QDialog(parent)
, ui(new Ui::topologyView)
,_pModel(nullptr)
,_treeView(nullptr)
{
ui->setupUi(this);
//setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint&Qt::WindowCloseButtonHint);
_pModel = new QStandardItemModel(this);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
_treeView = new TopologyTree(this);
ui->verticalLayout->addWidget(_treeView);
_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
}
TopologyView::~TopologyView()
@ -24,10 +28,10 @@ TopologyView::~TopologyView()
void TopologyView::initial()
{
connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &TopologyView::onIndexRbtnClicked);
connect(ui->treeView, &QTreeView::clicked, this, &TopologyView::onItemClicked);
connect(_treeView, &QTreeView::customContextMenuRequested, this, &TopologyView::onIndexRbtnClicked);
connect(_treeView, &QTreeView::clicked, this, &TopologyView::onItemClicked);
connect(_pModel, &QStandardItemModel::itemChanged, this, &TopologyView::onItemChanged);
ui->treeView->setHeaderHidden(true);
_treeView->setHeaderHidden(true);
// 设置模型的列数
_pModel->setColumnCount(1);
@ -40,18 +44,23 @@ void TopologyView::initial()
_pModel->appendRow(rootItem);
// 创建树视图
ui->treeView->setModel(_pModel);
_treeView->setModel(_pModel);
// 展开所有节点
ui->treeView->expandAll();
_treeView->expandAll();
// 显示树视图
ui->treeView->setWindowTitle(QObject::tr("拓扑树"));
_treeView->setWindowTitle(QObject::tr("拓扑树"));
}
void TopologyView::loadTopologyFromDB()
{
}
void TopologyView::onIndexRbtnClicked(const QPoint &pos)
{
// 获取当前点击的位置对应的索引
QModelIndex index = ui->treeView->indexAt(pos);
QModelIndex index = _treeView->indexAt(pos);
if (!index.isValid()) {
return; // 如果点击的是空白区域,直接返回
}
@ -102,7 +111,7 @@ void TopologyView::onIndexRbtnClicked(const QPoint &pos)
info.sUuid = uuid;
emit entityCreate(info);
ui->treeView->expandAll();
_treeView->expandAll();
});
menu.addAction(addAction);
@ -126,14 +135,14 @@ void TopologyView::onIndexRbtnClicked(const QPoint &pos)
info.sParentId = sParentid;
emit entityCreate(info);
ui->treeView->expandAll();
_treeView->expandAll();
});
menu.addAction(addAction);
}
else if(nLevel == 3) //station
{
QAction *addAction = new QAction("添加组态图", this);
/*QAction *addAction = new QAction("添加组态图", this);
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
@ -150,14 +159,14 @@ void TopologyView::onIndexRbtnClicked(const QPoint &pos)
info.sParentId = sParentid;
emit entityCreate(info);
ui->treeView->expandAll();
_treeView->expandAll();
});
menu.addAction(addAction);
menu.addAction(addAction);*/
}
else if(nLevel == 4) //组态图
{
QAction *addAction = new QAction("添加子组态图", this);
/*QAction *addAction = new QAction("添加子组态图", this);
QString sText = item->text();
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
@ -174,17 +183,17 @@ void TopologyView::onIndexRbtnClicked(const QPoint &pos)
info.sParentId = sParentid;
emit entityCreate(info);
ui->treeView->expandAll();
_treeView->expandAll();
});
menu.addAction(addAction);
menu.addAction(addAction);*/
}
if(nLevel != -1) //除了根节点其余都能删除
{
QAction *delAction = new QAction("删除", this);
connect(delAction,&QAction::triggered,this,[&](){
QModelIndex currentIndex = ui->treeView->currentIndex();
QModelIndex currentIndex = _treeView->currentIndex();
if(currentIndex.isValid())
{
QStandardItem* pItem = _pModel->itemFromIndex(currentIndex);
@ -210,7 +219,7 @@ void TopologyView::onIndexRbtnClicked(const QPoint &pos)
}
// 在点击位置显示菜单
menu.exec(ui->treeView->mapToGlobal(pos));
menu.exec(_treeView->mapToGlobal(pos));
}
void TopologyView::onItemChanged(QStandardItem *item)

24
ui/diagramView.ui Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>diagramView</class>
<widget class="QDialog" name="diagramView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>199</width>
<height>455</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="treeView"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -19,18 +19,7 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="treeView">
<property name="minimumSize">
<size>
<width>170</width>
<height>430</height>
</size>
</property>
</widget>
</item>
</layout>
<layout class="QVBoxLayout" name="verticalLayout"/>
</widget>
<resources/>
<connections/>