add auto expand logic

This commit is contained in:
baiYue 2026-05-06 08:51:47 +08:00
parent 80cfa5e815
commit 665635e839
24 changed files with 297 additions and 7 deletions

View File

@ -43,7 +43,7 @@ void ReactorItem::draw(QPainter *painter, const QRectF &rect)
painter->setPen(pen);
painter->setBrush(brush);
// 绘制矩形
/*// 绘制矩形
if (m_cornerRadius > 0) {
painter->drawRoundedRect(rect, m_cornerRadius, m_cornerRadius);
} else {
@ -63,7 +63,7 @@ void ReactorItem::draw(QPainter *painter, const QRectF &rect)
Qt::AlignLeft | Qt::AlignTop,
sizeText);
painter->restore();
}
}*/
painter->restore();
}

View File

@ -65,6 +65,7 @@ set(DIAGRAMCAVAS_HEADER_FILES
include/graphicsItem/handleRect.h
include/graphicsItem/handleText.h
include/graphicsItem/itemPort.h
include/graphicsItem/itemExtend.h
include/graphicsItem/electricBayItem.h
include/graphicsItem/itemControlHandle.h
include/graphicsItem/graphicsBaseItem.h
@ -211,6 +212,7 @@ set(DIAGRAMCAVAS_SOURCE_FILES
source/graphicsItem/handleRect.cpp
source/graphicsItem/handleText.cpp
source/graphicsItem/itemPort.cpp
source/graphicsItem/itemExtend.cpp
source/graphicsItem/electricBayItem.cpp
source/graphicsItem/itemControlHandle.cpp
source/graphicsItem/graphicsBaseItem.cpp

View File

@ -74,6 +74,7 @@ public slots:
void runPage(const QString); //运行时
void onSignal_runPage();
void onSignal_deletePage();
void onSignal_extendClick(bool);
void onSignal_activatePage(const QString& name);
void onSignal_panelDelete(const QString& name,int nType); //type:0editorPanel,1drawPanel

View File

@ -50,6 +50,7 @@ public:
QMap<QString, PluginTypeInfo> m_pluginInfo;
QMdiArea* m_mdiArea = nullptr;
int _curMode = 0; //0编辑1运行
int _operateMode = 0; //操作模式 0正常1扩展
// 私有方法
void initialImpl();
@ -69,6 +70,7 @@ public:
void deletePanel(const QString& name,int nType);
void setCurMode(int);
int getCurMode() const {return _curMode;}
int getOperateMode() const {return _operateMode;}
//显示属性相关
void showPropertyDlgImpl(); // 显示属性页

View File

@ -139,6 +139,8 @@ public:
void updateHMICustomRef(QUuid hmiId,QString model,QUuid itemId,QByteArray hash256); //更新customImg引用
void updateItemPropertyVisibleLst(); //更新对象的属性可见性列表(属性栏使用)
QMap<QUuid, QMap<QString, bool*>> getProVisibleRef(){return _mapSelectedRefs;}
QMap<QUuid,QList<QUuid>> calculateUnlinkItem(GraphicsFunctionModelItem*); //计算存在连接但未绘制的item<端口id(无表示母线端口),lst<关联对象id>>
/************************数据显示*************************/
void setCurItemPropertyDlg(ItemPropertyDlg* p) {m_curPropertyDlg = p;}
ItemPropertyDlg* getCurItemPropertyDlg() {return m_curPropertyDlg;}

View File

@ -12,6 +12,9 @@ public:
virtual ~ElectricFunctionModelSvgItemCT();
virtual ElectricFunctionModelSvgItemCT* clone() const override;
void setItemType(int n){_itemType = n;}
virtual void onHoverEnter(QGraphicsSceneHoverEvent* event) override;
virtual void onHoverLeave(QGraphicsSceneHoverEvent* event) override;
private:
void initial();
protected:

View File

@ -12,6 +12,9 @@ public:
virtual ~ElectricFunctionModelSvgItemPT();
virtual ElectricFunctionModelSvgItemPT* clone() const override;
void setItemType(int n){_itemType = n;}
virtual void onHoverEnter(QGraphicsSceneHoverEvent* event) override;
virtual void onHoverLeave(QGraphicsSceneHoverEvent* event) override;
protected:
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
private:

View File

@ -33,10 +33,16 @@ public:
QSharedPointer<GraphicsEventContext> eventContext() const {
return m_eventContext;
}
virtual void onHoverEnter(QGraphicsSceneHoverEvent* event);
virtual void onHoverLeave(QGraphicsSceneHoverEvent* event);
protected:
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
void executeEvent(const EventData& event);
void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
protected:
bool m_isHovered = false;
BaseItemPropertyProxy* _pPropertyProxy; //属性页代理
QVector<EventData> m_events; //HMI组态的事件
QSharedPointer<GraphicsEventContext> m_eventContext;

View File

@ -0,0 +1,30 @@
#ifndef ITEMEXTEND_H
#define ITEMEXTEND_H
/**********手动扩展结构标志***********/
#include "graphicsItem/handleRect.h"
class ElectricFunctionModelConnectLineItem;
class ItemExtend : public HandleRect
{
Q_OBJECT
public:
ItemExtend(QGraphicsItem *parent);
virtual ~ItemExtend();
public:
void setSourcePortId(const QString& id) {_sourcePortId = id;}
QString getSourcePortId() {return _sourcePortId;}
protected:
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
private:
QString _uuid;
QString _sourcePortId; //被哪个port生成
int m_penWidth;
QColor m_normalColor;
QColor m_hoverColor;
QColor m_currentColor;
};
#endif

View File

@ -38,9 +38,7 @@ enum OperationMode
OM_linkMove, //连接线移动
};
class GraphicsProjectModelItem;
using ItemMap = QMap<QString,QMap<QString,GraphicsProjectModelItem*>>;
class GraphicsFunctionModelItem;
class BaseSelector : public QObject
{
@ -59,6 +57,8 @@ public:
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*,DiagramMode);
virtual void dropEvent(QGraphicsSceneDragDropEvent *event, DesignerScene*,DiagramMode);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event,DesignerScene*,DiagramMode);
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event,DesignerScene*,QGraphicsItem*,DiagramMode);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event,DesignerScene*,QGraphicsItem*,DiagramMode);
SelectorType getSelectorType() { return m_type; }
//void setOperationMode(OperationMode m) { m_opMode = m; }

View File

@ -22,7 +22,7 @@ public:
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*,DiagramMode sceneMode);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*,DiagramMode sceneMode);
private:
GraphicsProjectModelItem* m_pParentItem;
GraphicsFunctionModelItem* m_pParentItem;
};
#endif

View File

@ -88,6 +88,7 @@ void DesignerScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent)
DiagramMode mode = m_pDrawingPanel->getMode();
m_pDrawingPanel->selectorManager()->getWorkingSelector()->mouseMoveEvent(mouseEvent, this,mode);
update();
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
else
QGraphicsScene::mouseMoveEvent(mouseEvent);

View File

@ -162,6 +162,12 @@ void DiagramCavas::onSignal_deletePage()
}
void DiagramCavas::onSignal_extendClick(bool bCheck)
{
Q_D(DiagramCavas);
d->_operateMode = bCheck?1:0;
}
void DiagramCavas::onSignal_activatePage(const QString& name)
{
Q_D(DiagramCavas);

View File

@ -2751,6 +2751,7 @@ void FixedPortsModel::previewHMI(SelectPanel* pPanel,QList<HierarchyItem> lst)
BaseProperty* pPro = dynamic_cast<BaseProperty*>(pItem->getProperty());
if(pPro){
auto pNewItem = pItem->clone();
pNewItem->setHandle(pPanel->getModelController());
if(pPro->type() == 8){
auto pLine = dynamic_cast<ElectricFunctionModelConnectLineItem*>(pNewItem);
if(pLine)
@ -2948,3 +2949,57 @@ void FixedPortsModel::updateItemPropertyVisibleLst()
++it;
}
}
QMap<QUuid,QList<QUuid>> FixedPortsModel::calculateUnlinkItem(GraphicsFunctionModelItem* pItem)
{
QMap<QUuid, QList<QUuid>> result;
if (pItem->getItemType() != GIT_link) //获取非电缆对象
{
QUuid nId = pItem->itemId();
auto lstConnect = TopologyManager::instance().getConnectionsFor(nId.toString());
for (auto &pConnect : lstConnect)
{
if (!pConnect) continue;
QString fromTerminalId = pConnect->fromTerminalId();
QString toTerminalId = pConnect->toTerminalId();
QString fromComponent = pConnect->fromComponent();
QString toComponent = pConnect->toComponent();
QPointF fromPos = getTerminalPos(fromTerminalId);
QPointF toPos = getTerminalPos(toTerminalId);
// 检查连接是否完整
QUuid fromTerminalUuid = QUuid(fromTerminalId);
QUuid toTerminalUuid = QUuid(toTerminalId);
QUuid fromItemId = QUuid(fromComponent);
QUuid toItemId = QUuid(toComponent);
// 检查from端位置是否为(0,0) - 视为未完整连接
if (fromPos == QPointF(0, 0))
{
// 记录from端terminal对应的对端itemId
if (!result.contains(fromTerminalUuid))
{
result[fromTerminalUuid] = QList<QUuid>();
}
result[fromTerminalUuid].append(toItemId);
}
// 检查to端位置是否为(0,0) - 视为未完整连接
if (toPos == QPointF(0, 0))
{
// 记录to端terminal对应的对端itemId
if (!result.contains(toTerminalUuid))
{
result[toTerminalUuid] = QList<QUuid>();
}
result[toTerminalUuid].append(fromItemId);
}
}
}
return result;
}

View File

@ -111,6 +111,7 @@ void ElectricFunctionModelSvgGroupCT::updateItem()
if(_nType == 1){
for(int i = 0;i < _nSize;++i){
ElectricFunctionModelSvgItemCT* p = new ElectricFunctionModelSvgItemCT(rec);
p->setHandle(_pHandle);
p->setItemType(_nType);
p->setMoveable(false);
p->loadSvg(m_mapSvg["ct"]);
@ -119,6 +120,7 @@ void ElectricFunctionModelSvgGroupCT::updateItem()
}
else if(_nType == 0){
ElectricFunctionModelSvgItemCT* p = new ElectricFunctionModelSvgItemCT(rec);
p->setHandle(_pHandle);
p->setItemType(_nType);
p->setMoveable(false);
p->loadSvg(m_mapSvg["zsct"]);

View File

@ -115,6 +115,7 @@ void ElectricFunctionModelSvgGroupPT::updateItem()
p->loadSvg(m_mapSvg["z"]);
p->setItemType(0);
}
p->setHandle(_pHandle);
p->setMoveable(false);
addSvgItem(p);
}

View File

@ -1,4 +1,6 @@
#include "graphicsItem/functionModelItem/electricFunctionModelSvgItemCT.h"
#include "baseDrawingPanel.h"
#include "util/selectorManager.h"
#include <QSvgRenderer>
#include <QPainter>
@ -125,4 +127,25 @@ void ElectricFunctionModelSvgItemCT::paint(QPainter* painter, const QStyleOption
}
}
void ElectricFunctionModelSvgItemCT::onHoverEnter(QGraphicsSceneHoverEvent* event) {
// 基类的基本处理
if(!_pHandle)
return;
auto mode = _pHandle->getParent()->getMode();
if(mode != DM_run)
return;
m_isHovered = true;
setOpacity(0.6);
_pHandle->getParent()->selectorManager()->getWorkingSelector()->hoverEnterEvent(event,_pHandle->getScene(),parentItem(),mode);
}
void ElectricFunctionModelSvgItemCT::onHoverLeave(QGraphicsSceneHoverEvent* event) {
if(!_pHandle)
return;
auto mode = _pHandle->getParent()->getMode();
if(mode != DM_run)
return;
m_isHovered = false;
setOpacity(1.0);
_pHandle->getParent()->selectorManager()->getWorkingSelector()->hoverLeaveEvent(event,_pHandle->getScene(),parentItem(),mode);
}

View File

@ -1,4 +1,6 @@
#include "graphicsItem/functionModelItem/electricFunctionModelSvgItemPT.h"
#include "baseDrawingPanel.h"
#include "util/selectorManager.h"
#include <QSvgRenderer>
#include <QPainter>
@ -81,6 +83,30 @@ void ElectricFunctionModelSvgItemPT::paint(QPainter* painter, const QStyleOption
}
}
void ElectricFunctionModelSvgItemPT::onHoverEnter(QGraphicsSceneHoverEvent* event) {
// 基类的基本处理
if(!_pHandle)
return;
auto mode = _pHandle->getParent()->getMode();
if(mode != DM_run)
return;
m_isHovered = true;
setOpacity(0.6);
_pHandle->getParent()->selectorManager()->getWorkingSelector()->hoverEnterEvent(event,_pHandle->getScene(),parentItem(),mode);
}
void ElectricFunctionModelSvgItemPT::onHoverLeave(QGraphicsSceneHoverEvent* event) {
if(!_pHandle)
return;
auto mode = _pHandle->getParent()->getMode();
if(mode != DM_run)
return;
m_isHovered = false;
setOpacity(1.0);
_pHandle->getParent()->selectorManager()->getWorkingSelector()->hoverLeaveEvent(event,_pHandle->getScene(),parentItem(),mode);
}
void ElectricFunctionModelSvgItemPT::initial()
{
setFlag(QGraphicsItem::ItemIsSelectable, false);

View File

@ -4,6 +4,8 @@
#include "baseItemPropertyProxy.h"
#include "graphicsItem/functionModelItem/graphicsEventContext.h"
#include "evetConfig/eventExecutor.h"
#include "baseDrawingPanel.h"
#include "util/selectorManager.h"
GraphicsFunctionModelItem::GraphicsFunctionModelItem(QGraphicsItem *parent)
: GraphicsProjectModelItem(parent)
@ -11,6 +13,7 @@ GraphicsFunctionModelItem::GraphicsFunctionModelItem(QGraphicsItem *parent)
{
m_eventContext = QSharedPointer<GraphicsEventContext>::create();
m_eventExecutor = QSharedPointer<EventExecutor>(new EventExecutor());
setAcceptHoverEvents(true);
}
GraphicsFunctionModelItem::GraphicsFunctionModelItem(const GraphicsFunctionModelItem& obj)
@ -18,6 +21,7 @@ GraphicsFunctionModelItem::GraphicsFunctionModelItem(const GraphicsFunctionModel
,_pPropertyProxy(nullptr)
{
//只做基本拷贝,用在预览显示
setAcceptHoverEvents(true);
}
GraphicsFunctionModelItem::~GraphicsFunctionModelItem()
@ -77,6 +81,25 @@ void GraphicsFunctionModelItem::triggerEvents(const QString& triggerType)
}
}
void GraphicsFunctionModelItem::onHoverEnter(QGraphicsSceneHoverEvent* event) {
// 基类的基本处理
auto mode = _pHandle->getParent()->getMode();
if(mode != DM_run)
return;
m_isHovered = true;
setOpacity(0.6);
_pHandle->getParent()->selectorManager()->getWorkingSelector()->hoverEnterEvent(event,_pHandle->getScene(),this,mode);
}
void GraphicsFunctionModelItem::onHoverLeave(QGraphicsSceneHoverEvent* event) {
auto mode = _pHandle->getParent()->getMode();
if(mode != DM_run)
return;
m_isHovered = false;
setOpacity(1.0);
_pHandle->getParent()->selectorManager()->getWorkingSelector()->hoverLeaveEvent(event,_pHandle->getScene(),this,mode);
}
void GraphicsFunctionModelItem::executeEvent(const EventData& event) {
m_eventExecutor->execute(event, this);
}
@ -87,6 +110,18 @@ void GraphicsFunctionModelItem::paint(QPainter* painter, const QStyleOptionGraph
Q_UNUSED(widget)
}
void GraphicsFunctionModelItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
onHoverEnter(event);
QGraphicsItem::hoverEnterEvent(event);
}
void GraphicsFunctionModelItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
onHoverLeave(event);
QGraphicsItem::hoverLeaveEvent(event);
}
/********************************功能模item组*************************************/
GraphicsFunctionModelGroup::GraphicsFunctionModelGroup(QGraphicsItem *parent)

View File

@ -0,0 +1,50 @@
#include <QPainter>
#include "graphicsItem/itemExtend.h"
ItemExtend::ItemExtend(QGraphicsItem *parent)
: HandleRect(parent)
{
setAcceptHoverEvents(true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemIsFocusable, true);
m_penWidth = 2;
m_normalColor = QColor(52, 152, 219); // 蓝色
m_hoverColor = QColor(41, 128, 185); // 深蓝
m_currentColor = m_normalColor;
}
ItemExtend::~ItemExtend()
{
}
void ItemExtend::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
// 绘制圆形背景
QBrush bgBrush(m_currentColor);
painter->setBrush(bgBrush);
painter->setPen(Qt::NoPen);
painter->drawEllipse(boundingRect());
// 绘制白色"+"号
QPen pen(Qt::white, m_penWidth);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::MiterJoin);
painter->setPen(pen);
QRectF rect = boundingRect().adjusted(4, 4, -4, -4);
qreal centerX = rect.center().x();
qreal centerY = rect.center().y();
qreal lineLength = rect.width() * 0.4;
// 横线
painter->drawLine(QLineF(centerX - lineLength/2, centerY,
centerX + lineLength/2, centerY));
// 竖线
painter->drawLine(QLineF(centerX, centerY - lineLength/2,
centerX, centerY + lineLength/2));
painter->restore();
}

View File

@ -5,6 +5,7 @@
#include <QMimeData>
#include <QMessageBox>
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/functionModelItem/graphicsFunctionModelItem.h"
#include "topologyManager.h"
#include "graphicsItem/itemPort.h"
#include "graphicsItem/functionModelItem/electricFunctionModelConnectLineItem.h"
@ -488,6 +489,10 @@ void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene
{
int a = 1;
}
else if(sceneMode == DM_run)
{
int a = 1;
}
}
void BaseSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene,DiagramMode sceneMode)
@ -702,6 +707,23 @@ void BaseSelector::contextMenuEvent(QGraphicsSceneContextMenuEvent *event,Design
}
}
void BaseSelector::hoverEnterEvent(QGraphicsSceneHoverEvent* event,DesignerScene* scene,QGraphicsItem* p,DiagramMode sceneMode)
{
auto pItem = dynamic_cast<GraphicsFunctionModelItem*>(p);
if(pItem){
auto mapLst = _model->calculateUnlinkItem(pItem);
int a = 1;
}
}
void BaseSelector::hoverLeaveEvent(QGraphicsSceneHoverEvent* event,DesignerScene* scene,QGraphicsItem* p,DiagramMode sceneMode)
{
auto pItem = dynamic_cast<GraphicsFunctionModelItem*>(p);
if(pItem){
}
}
void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
{
QGraphicsView *view = scene->getView();

View File

@ -3,6 +3,7 @@
#include <QGraphicsView>
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/handleText.h"
#include "graphicsItem/functionModelItem/graphicsFunctionModelItem.h"
SubMovingSelector::SubMovingSelector(FixedPortsModel* model,QObject *parent)
: BaseSelector(model,parent)
@ -33,7 +34,7 @@ void SubMovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, Designer
ItemControlHandle* pHandle = qgraphicsitem_cast<ItemControlHandle*>(items.first());
if(pHandle)
{
GraphicsProjectModelItem* item = dynamic_cast<GraphicsProjectModelItem*>(pHandle->getParentPtr());
GraphicsFunctionModelItem* item = dynamic_cast<GraphicsFunctionModelItem*>(pHandle->getParentPtr());
if(item)
{
if(ms_nDragHandle >= H_textCaption && ms_nDragHandle < H_connect) //移动文本

View File

@ -212,6 +212,7 @@ void CMainWindow::initializeAction()
connect(ui->actionNew,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_addPage);
connect(ui->actionSave,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_savePage);
connect(ui->actionDelete,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_deletePage);
connect(ui->actionExtend,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_extendClick);
QAction* actNewEditor = ui->menuFile->addAction(QString::fromWCharArray(L"新建组态"));

View File

@ -120,6 +120,7 @@ QMenu#menubar {
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="separator"/>
<addaction name="actionExtend"/>
</widget>
<action name="actionNew">
<property name="icon">
@ -324,6 +325,23 @@ QMenu#menubar {
<string>运行</string>
</property>
</action>
<action name="actionExtend">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="QIcon::ThemeIcon::InsertLink"/>
</property>
<property name="text">
<string>智能扩展</string>
</property>
<property name="toolTip">
<string>智能扩展</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
</widget>
<resources/>
<connections/>