#include "WindowAppBlockPort.h" #include "WindowAppItemInterface.h" #include "Pou.h" #include "DialogPortValue.h" WindowAppBlockPort::WindowAppBlockPort(TOOL* pNewPort, POU* Pou, bool bShowOnly, QGraphicsObject* parent) : WindowAppBlockBase(pNewPort, Pou, bShowOnly, parent) { setFlag(QGraphicsItem::ItemIsMovable); setFlag(QGraphicsItem::ItemIsSelectable); setFlag(QGraphicsItem::ItemSendsGeometryChanges); updateRect(); // 初始化菜单 createContextMenu(); } /// /// 根据用户的输入实时更新矩形区域的尺寸 /// void WindowAppBlockPort::updateRect() { // 计算高度 int blockHeight = PBD_BASIC_HEIGHT; // 计算宽度 int blockWidth = PBD_BASIC_WIDTH; // 2021-3-28增加,根据工具名字字符的宽度计算实际需要的宽度 QRect textRect = QFontMetrics(FONT_INF).boundingRect(m_strInfTitle); if (textRect.width() > PBD_BASIC_WIDTH - PBD_TEXT_GAP_WIDTH) { blockWidth = textRect.width() + PBD_TEXT_GAP_WIDTH; } // 主体矩形区域 blockRect.setRect( -blockWidth / 2, -blockHeight, blockWidth, blockHeight ); // 总体矩形边界(未计算Interface的范围) blockBoundingRect.setRect( blockRect.left(), blockRect.top() - TBD_INDEX_HEIGHT / 2, blockRect.width() + TBD_SHADOW_COUNT * PEN_LINE_WIDTH, blockRect.height() + TBD_INDEX_HEIGHT / 2 + TBD_SHADOW_COUNT * PEN_LINE_WIDTH ); } /// /// 绘制功能块 /// /// /// /// void WindowAppBlockPort::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { painter->setRenderHint(QPainter::Antialiasing, true); WindowAppBlockBase::paint(painter, option, widget); // bSel = isSelected(); Q_UNUSED(widget); painter->save(); //// 每次绘制之前都更新一下矩形区域 //UpdateRect(); // 绘制外框 DrawBlock(painter); // 绘制阴影 //DrawBlockShadow(painter); //// 绘制序号 //DrawIndex(painter); ////// 绘制接口 ////DrawInterface(painter); painter->restore(); } /// /// 绘制功能块 /// /// void WindowAppBlockPort::DrawBlock(QPainter* painter) { WindowAppBlockBase::DrawBlock(painter); if (m_toolInfo->execParams.nRetValue == VPEnum::RETURN_VALUE::Error ) { painter->setBrush(QColor(255,0,0) ); // 绘制主体 painter->drawRect(blockRect); } } /// /// 添加接口 /// void WindowAppBlockPort::addItemInterfaces() { // 为本Block添加新的ItemInterface //for (TOOL_INTERFACE* pInf : qAsConst(toolInfo->Interfaces)) //{ WindowAppItemInterface* pNewItemInf = new WindowAppItemInterface( m_toolInfo->Interfaces[0], m_pPou, this->m_toolInfo, m_bShowOnly, this ); if (!m_bShowOnly) { // Pou中保存此接口信息 m_pPou->registerInterface(pNewItemInf, m_toolInfo->Interfaces[0]); } // 保存接口Item信息 m_itemInterfaces.append(pNewItemInf); // 界面中添加此Interface(设置为从属关系之后,都不需要手工添加此Item了,真是方便啊) // scene()->addItem(pNewItemInf); //} // 更新Interface的位置 WindowAppBlockBase::updateInterfacesPostion(); } /// /// 初始化功能块的右键菜单 /// void WindowAppBlockPort::createContextMenu() { WindowAppBlockBase::createContextMenu(); //connect(executeAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuExecute); //connect(executeAllAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuExecuteAll); connect(deleteAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuDelete); // connect(propertyAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuProperty); contextMenu = new QMenu(); //contextMenu->addAction(executeAction); //contextMenu->addAction(executeAllAction); //contextMenu->addSeparator(); contextMenu->addAction(deleteAction); // Port功能块暂时不需要属性框 //contextMenu->addSeparator(); //contextMenu->addAction(propertyAction); } /// /// 菜单 - Delete /// void WindowAppBlockPort::onMenuDelete() { //// 检查是否可以被删除 //if (!WindowAppBlockBase::couldBeDeleted()) //{ // return; //} // 2021-6-6 如果有绑定的接口变量,则接口变量的引用计数要 - 1 if (this->m_toolInfo->isBinded()) { this->m_toolInfo->bindedInterface()->nRefCount--; } // 2022-10-4,调用基类函数进行删除 WindowAppBlockBase::onDeleteItem(); //// 逻辑数据删除 //m_pPou->ToolDelete(this); //// 从界面中移除此功能块 //scene()->removeItem(this); } /// /// 鼠标双击时弹出变量选择对话框 /// /// void WindowAppBlockPort::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) { if (event->button() != Qt::LeftButton || m_bShowOnly) { return; } // 显示变量选择对话框 DialogPortValue dlgPortValue(m_toolInfo, m_pPou); int res = dlgPortValue.exec(); if (res != QDialog::Accepted) { return; } // 获取用户选择的接口信息 _INTERFACE* pSelInf = const_cast<_INTERFACE*>(dlgPortValue.GetSelectedInf()); // 绑定此接口 this->bindInterface(pSelInf); // 重绘本功能块,用于绑定接口文字的及时更新 this->update(); QGraphicsItem::mouseDoubleClickEvent(event); } /// /// 绑定一个接口 /// /// void WindowAppBlockPort::bindInterface(_INTERFACE* pNewInf) { // 2021-6-6增加,保存Port绑定的源接口指针 this->m_toolInfo->bindPortInterface(pNewInf); // 将本变量的值和接口信息,保存到Port的工具信息中 // m_strInfTitle = pNewInf->strFullName + PORT_INF_POSTFIX; m_strInfTitle = genPortInfName(pNewInf); m_pPou->bindPortAndInterface(this, pNewInf, m_strInfTitle); // 根据新的名字长度信息更新本矩形框 updateRect(); // 更新接口的位置及尺寸 WindowAppBlockBase::updateInterfacesPostion(); // 2021-6-6 增加,此处还得需要调整一下link连线的位置(如果有的话),因为port的尺寸会有变动 emit blockMoveSignal(this); } /// /// 2022-3-22 为Port中显示的接口名称做调整(局部变量不加Pou前缀,全局变量加Pou前缀) /// /// /// QString WindowAppBlockPort::genPortInfName(const _INTERFACE* pNewInf) { QString strPortGroup = this->m_toolInfo->strPouName; QString strInfGroup = pNewInf->parent()->strPouName; // 如果和本Port在同一个Pou范围内 if (strPortGroup == strInfGroup) { // 如果是局部变量,那么没有实例名 if (pNewInf->parent()->Type == TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE) { return (pNewInf->strName + PORT_INF_POSTFIX); } // 如果是Tool,则加上实例名 else if(pNewInf->parent()->Type == TOOL_TYPE::TOOL_TYPE_STANDARD) { return (pNewInf->parent()->strInstanceName + "." + pNewInf->strName + PORT_INF_POSTFIX); } } // 否则,加上Pou名称返回 return (pNewInf->strFullName + PORT_INF_POSTFIX); }