#include "DialogPortValue.h" #include "PouManager.h" #include "GvlManager.h" DialogPortValue::DialogPortValue(const TOOL* port, POU* localPou, QWidget *parent) : QDialog(parent) , portInfo(port) , m_pLocalPou(localPou) { ui.setupUi(this); // 对话框风格初始化 initUI(); //// 添加兼容的工具到树形结构中 //AddCompatibleToolsToTree(); //ui.treeTool->installEventFilter(this); } DialogPortValue::~DialogPortValue() { } /// /// 对话框初始化 /// void DialogPortValue::initUI() { // 设置对话框标题 this->setWindowTitle(("Port Interface Selection")); this->setAttribute(Qt::WA_QuitOnClose); this->setWindowModality(Qt::ApplicationModal); // ComboBox // 分别添加当前的Pou和全局变量(每一个全局变量是一个页面,Pou接口和全局变量是一个页面) // 2022-4-2 修改,默认显示本Port所属Pou的分组 ui.comboValueGroup->addItem(m_pLocalPou->pouName()); // 获取全部的GVL分组,并添加其中的全局变量分组 m_pAllVariables = g_pGvlManager->getAllGvls(); QMapIterator it(*m_pAllVariables); while (it.hasNext()) { const GVL* pGvl = it.next().value(); if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE) { ui.comboValueGroup->addItem(it.key()); } } // 硬件组态分组 ui.comboValueGroup->addItem(GROUP_NAME_HARDWARE); ui.comboValueGroup->setCurrentIndex(0); this->onComboGroupChanged(0); //ui.comboValueGroup->addItem(("Global Variables")); //// 初始化为按Pou来选择 //ui.comboValueGroup->setCurrentIndex(COMBO_INDEX_POU); //// 添加当前Pou兼容的工具到树形结构中 // AddCompatibleToolsToTree(); // m_SelMode = PORT_SEL_MODE::PORT_SEL_POU; // 添加当前兼容的Gvl变量到树形结构中 // AddCompatibleVariablesToTree(); // ui.comboValueGroup->setCurrentIndex(0); // m_SelMode = PORT_SEL_MODE::PORT_SEL_GVL; // Tree // 1列 ui.treeTool->setColumnCount(1); // 隐藏表头 ui.treeTool->setHeaderHidden(true); // 显示虚线 ui.treeTool->setStyle(QStyleFactory::create("windows")); // 槽函数 connect(ui.selectButton, SIGNAL(clicked()), this, SLOT(onButtonSelectClicked())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(ui.comboValueGroup, SIGNAL(currentIndexChanged(int)),this,SLOT(onComboGroupChanged(int))); // 设置固定窗体大小 this->setFixedSize(484, 487); //this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); } /// /// 添加兼容的工具到树形结构中 /// void DialogPortValue::AddPouToolsToTree(const POU* pPou) { // 添加适配的标准工具 const QVector& allTools = pPou->GetAllStandardTools(); QVectorIterator i(allTools); while (i.hasNext()) { const TOOL* pTool = i.next(); //// 只添加标准工具(允许绑定goto工具) //if (!pTool->isStandardTool()) //{ // continue; //} // 按照工具名称添加节点 QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName); // 继续添加接口 int nInfCount = 0; for (_INTERFACE* pInf : pTool->Interfaces) { // 只添加和Port输入输出类型相同的接口 // 而且隐藏的也不显示 if (pInf->Direction == portInfo->Interfaces[0]->Direction && pInf->bEnable) { // 如果Port已经绑定了变量类型,那么变量类型也需要相同 if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown && !pInf->isSameTypeTo(portInfo->Interfaces[0])) { continue; } // 所有条件都符合,才会出现在列表中 AddInterfaceTreeItem(pToolItem, pInf); nInfCount++; } } // 如果没有有效的接口,则删除掉刚刚添加的Tool节点 if (nInfCount <= 0) { ui.treeTool->removeItemWidget(pToolItem, 0); delete(pToolItem); } } // 将树形结构展开 ui.treeTool->expandAll(); } /// /// 添加兼容的Pou变量到树形结构中(返回是全局变量、局部变量) /// bool DialogPortValue::AddPouVariablesToTree(const QString& strGroup) { bool bIsGlobal = false; // 获取全部的GVL变量 m_pAllVariables = g_pGvlManager->getAllGvls(); // 首先找到用户选择的分组 QMapIterator it(*m_pAllVariables); while (it.hasNext()) { if (it.next().key() != strGroup) { continue; } // 找到当前变量集 const GVL* pGvl = it.value(); // 首先判断是全局变量还是局部变量 if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE) { bIsGlobal = true; } else { bIsGlobal = false; } // 将变量信息添加到树形结构中 QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(pGvl->Type); const VARIABLES& vars = it.value()->Variables; // 继续添加变量 for (const VARIABLE* var : vars) { // 如果Port已经绑定了变量类型,那么变量类型也需要相同 // 注:全局变量无需考虑方向,所有方向都可以设置 if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown && var->value.type != portInfo->Interfaces[0]->value.type) { continue; } // 所有条件都符合,才会出现在列表中 AddVariableTreeItem(pGroupItem, var); } // 将树形结构展开 ui.treeTool->expandAll(); break; } return bIsGlobal; //// 获取全部的GVL分组,并添加 //m_pAllVariables = g_pVariablesManager->getAllGlobalVariables(); //QHashIterator it(*m_pAllVariables); //while (it.hasNext()) //{ // // ui.comboValueGroup->addItem(it.next().key()); // QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(it.next().key()); // const VARIABLES& vars = it.value()->Variables; // // 继续添加变量 // for (const VARIABLE* var : vars) // { // // 如果Port已经绑定了变量类型,那么变量类型也需要相同 // // 注:全局变量无需考虑方向,所有方向都可以设置 // if (portInfo->Interface->value.Type != VALUE_TYPE::Unknown_Type // && var->value.Type!=portInfo->Interface->value.Type) // { // continue; // } // // 所有条件都符合,才会出现在列表中 // AddVariableTreeItem(pGroupItem, var); // } //} //// 将树形结构展开 //ui.treeTool->expandAll(); } /// /// 添加兼容的硬件工具 /// void DialogPortValue::AddHdwToolsToTree() { AddPouToolsToTree(g_pPouManager->getHdwPou()); } /// /// 添加兼容的硬件局部变量 /// void DialogPortValue::AddHdwVariablesToTree() { // 获取全部的GVL变量 m_pAllVariables = g_pGvlManager->getAllGvls(); // 首先找到用户选择的分组 QMapIterator it(*m_pAllVariables); while (it.hasNext()) { if (it.next().key() != GROUP_NAME_HARDWARE) { continue; } // 找到当前变量集 const GVL* pGvl = it.value(); // 将变量信息添加到树形结构中 QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(pGvl->Type); const VARIABLES& vars = it.value()->Variables; // 继续添加变量 for (const VARIABLE* var : vars) { // 如果Port已经绑定了变量类型,那么变量类型也需要相同 // 注:全局变量无需考虑方向,所有方向都可以设置 if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown && var->value.type != portInfo->Interfaces[0]->value.type) { continue; } // 所有条件都符合,才会出现在列表中 AddVariableTreeItem(pGroupItem, var); } // 将树形结构展开 ui.treeTool->expandAll(); break; } } /// /// 添加Tool子节点 /// /// QTreeWidgetItem* DialogPortValue::AddToolTreeItem(const QString& toolName) { QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(toolName)); newItem->setIcon(0, QIcon(":/image/tool_tree_item.png")); // 使父节点不可选中 newItem->setFlags(Qt::ItemIsEnabled); ui.treeTool->addTopLevelItem(newItem); return newItem; } /// /// 添加接口子节点 /// void DialogPortValue::AddInterfaceTreeItem(QTreeWidgetItem* pToolItem, const _INTERFACE* pInf) { QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(pInf->strName)); if (pInf->Direction == INF_DIRECTION::INF_DIR_OUT) { newItem->setIcon(0, QIcon(":/image/Output.png")); } else { newItem->setIcon(0, QIcon(":/image/Input.png")); } pToolItem->addChild(newItem); // 将新加入的item和对应的Interface绑定 m_ItemInfs.insert(newItem, pInf); } /// /// 添加变量分组子节点 /// /// /// QTreeWidgetItem* DialogPortValue::AddVariableGroupTreeItem(TOOL_TYPE varType) { QStringList strTitle; if (varType == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE) { strTitle.push_back("Global Variables"); } else { strTitle.push_back("Local Variables"); } QTreeWidgetItem* newItem = new QTreeWidgetItem(strTitle); newItem->setIcon(0, QIcon(":/image/gvl_group_tree_item.png")); // 使父节点不可选中 newItem->setFlags(Qt::ItemIsEnabled); ui.treeTool->addTopLevelItem(newItem); return newItem; } /// /// 添加变量子节点 /// /// /// void DialogPortValue::AddVariableTreeItem(QTreeWidgetItem* pToolItem, const VARIABLE* var) { // 添加的节点命名规则为 变量类型:变量名字 QString strNodeName = var->strNameWithType + "[" + Utility::getValueString(var->value.Ptr, var->value.type) + "]"; // strNodeName = // Utility::getTypeString(var->value.type) // + ": " + var->strName + // " [" + Utility::getValueString(var->value.Ptr, var->value.type) + "]"; // 根据名字建立新的节点 QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(strNodeName)); // newItem->setIcon(0, QIcon(":/image/Output.png")); // 根据当前Port的输入输出选择方向 if (portInfo->Interfaces[0]->Direction == INF_DIRECTION::INF_DIR_OUT) { newItem->setIcon(0, QIcon(":/image/Output.png")); } else { newItem->setIcon(0, QIcon(":/image/Input.png")); } pToolItem->addChild(newItem); // 将新加入的item和对应的Variable绑定 m_ItemInfs.insert(newItem, var); } /// /// select按钮 /// void DialogPortValue::onButtonSelectClicked() { // 获取用户选择的节点 QList selItems = ui.treeTool->selectedItems(); if (selItems.size() <= 0) { // 如果选择的节点无效,则不允许关闭 Utility::VPCriticalMessageBox(" The interface selected is invalid!"); selInf = nullptr; return; } // 获取用户选择的接口或变量 selInf = m_ItemInfs[selItems[0]]; this->accept(); } /// /// Combo框选择变更时,需要切换对应的变量列表 /// /// void DialogPortValue::onComboGroupChanged(int nIndex) { Q_UNUSED(nIndex); // 先将当前的树形控件及对应数据结构全部清空 ui.treeTool->clear(); m_ItemInfs.clear(); // 获取当前选中的分组名称 QString strGroup = ui.comboValueGroup->currentText(); // 首先判断是不是硬件组态分组 if (strGroup == GROUP_NAME_HARDWARE) { // 添加硬件变量 // AddHdwVariablesToTree(); // 添加硬件工具 AddHdwToolsToTree(); return; } // 如果是Pou相关的,则按Pou的逻辑处理 // 根据分组首先添加对应的Pou变量 bool bIsGlobal = AddPouVariablesToTree(strGroup); // 然后如果选择的是Pou页面,则继续添加Tool的接口变量 if (!bIsGlobal) { AddPouToolsToTree(m_pLocalPou); } } ///// ///// 事件过滤器,拦截发往treeTool的双击事件 ///// ///// ///// ///// //bool DialogPortValue::eventFilter(QObject* target, QEvent* event) //{ // if (target == ui.treeTool) // { // // qDebug() << event->type(); // // if (event->type() == QEvent::MouseButtonPress) // { // // 获取用户选择的节点 // QList selItems = ui.treeTool->selectedItems(); // // if (selItems.size() <= 0) // { // return true; // } // else // { // QMessageBox::critical(this, "Vision Plus", " The interface selected is invalid!"); // } // // this->accept(); // } // } // // // return QDialog::eventFilter(target, event); //} ///// ///// 鼠标双击,直接选定接口 ///// ///// //void DialogPortValue::mouseDoubleClickEvent(QMouseEvent* event) //{ // // 获取用户选择的节点 // QList selItems = ui.treeTool->selectedItems(); // // if (selItems.size() <= 0) // { // return; // } // else // { // QMessageBox::critical(this, "Vision Plus", " The interface selected is invalid!"); // } // // this->accept(); //}