#include "TemplateProgramPage.h" #include #include #include "Src/Common/JSignalSlotManager.h" std::unordered_map TemplateProgramPage::m_IdIsUsedMap; TemplateProgramPage::TemplateProgramPage(QWidget* parent) : QWidget(parent) { ui.setupUi(this); setStyleSheet( "QWidget { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F1F4FD, stop: 1 #E5E4F6); }" "QDoubleSpinBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }" "QSpinBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }" "QLineEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }" "QCheckBox::indicator { width: 20px; height: 20px; }" "QCheckBox::indicator:unchecked { background-color: #FFFFFF; border-radius: 2px; }" "QComboBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }" "QComboBox::drop-down { width: 20px; }" "QPushButton { background: #D0D0E8; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }" // Button background color "QPushButton:hover { background-color: #B0B0D8; }" // Lighter color on hover "QPushButton:pressed { background-color: #A0A0C8; }" // Darker color on press ); ui.comboBoxCurStraTemp->hide(); ui.pushButtonSaveTemp->hide(); ui.comboBoxCurStrategy->setEnabled(false); //QTabWidget* m_tabWidget = new QTabWidget(this); // 这里创建 QTabWidget //ui.verticalLayoutTemplate->addWidget(m_tabWidget); // 将 QStackedWidget 添加到布局中 // 隐藏整个标签栏(包括标签名称) ui.tabWidget->tabBar()->hide(); ui.pushButton1->hide(); ui.pushButton2->hide(); ui.pushButton3->hide(); ui.pushButton4->hide(); ui.pushButtonDelete->setIcon(QIcon(":/images/Program/deleteOuter.png")); ui.pushButtonAddStrategy->setIcon(QIcon(":/images/Program/addMatrix.png")); ui.pushButtonAddTemplate->setIcon(QIcon(":/images/Program/addMatrix.png")); m_manageDB = CManageDB::GetInstance(); if (m_manageDB == nullptr) return; m_pProduct = m_manageDB->GetCProduct(); if (m_pProduct == nullptr) return; m_pTemplateCViewInterface = ns_module::CViewInterface::GetInstance(); m_CamerAndLamp = ns_module::CCamerAndLamp::GetInstance(); initPage(); } void TemplateProgramPage::initPage() { m_vecPrStrategy = m_manageDB->GetCProduct()->GetPrStrategy(); m_vecPrTemplate = m_manageDB->GetCProduct()->GetPrTemplate(); // Create Add PrStrategyPage for (int j = 0; j < m_vecPrStrategy.size(); j++) { AddPrStrategyPage(j, m_vecPrStrategy[j]); } // Create PrStrategyPage for (int j = 0; j < m_vecPrTemplate.size(); j++) { AddPrTemplatePage(j, m_vecPrTemplate[j]); } connect(ui.pushButtonSetPrStrategyRef, &QPushButton::clicked, this, [this]() { if (!curentPrStrategy) { JMessageTip::Message_warning(tr("Error !", "错误!"), tr("No strategy selected!", "没有选择策略!"), this); return; } // 设置 SetPrStrategyRef m_CamerAndLamp->SetPrStrategyRef(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId); curentPrStrategy = m_pProduct->GetPrStrategy(curentPrStrategy->iStrategyId); UpdatePrStrategyUI(); // 添加提示信息 JMessageTip::Message_information(tr("Success!","成功 !"), tr("Strategy reference has been set successfully."), this); }); // Add策略 connect(ui.pushButtonAddStrategy, &QPushButton::clicked, this, &TemplateProgramPage::onAddStrategyClicked); // Delete策略 connect(ui.pushButtonDelete, &QPushButton::clicked, this, &TemplateProgramPage::onDeleteStrategyClicked); // Add模板 connect(ui.pushButtonAddTemplate, &QPushButton::clicked, this, &TemplateProgramPage::onAddTemplateClicked); } void TemplateProgramPage::onAddStrategyClicked() { // 模拟 MODULE_LIST 列表中的各个项 QStringList moduleNames = { tr("WafflePack", "华夫盒"), tr("WaffleHead", "华夫盒取晶头"), tr("WaffleTransferTable", "华夫盒中转台"), tr("WaferTable", "晶片台"), tr("Ejector", "顶针"), tr("WaferHead", "晶片取晶头"), tr("WaferTransferTable", "晶片台中转台"), tr("BondTable", "绑头"), tr("EutecticTable", "共晶台"), tr("DispenseHead", "点胶头"), tr("BondHead", "固晶头"), tr("SoliderTable", "流道"), tr("Load1", "上料"), tr("Unload1", "下料"), tr("NozzleTable", "吸嘴架"), tr("MaterialBox1", "料盒") }; // 创建一个对话框显示模块选择列表 QDialog dialog(this); dialog.setWindowTitle(tr("Choose Module", "选择模块")); QVBoxLayout* layout = new QVBoxLayout(&dialog); QListWidget* listWidget = new QListWidget(&dialog); // 填充模块选项 for (int i = 0; i < moduleNames.size(); ++i) { QListWidgetItem* item = new QListWidgetItem(moduleNames[i]); item->setData(Qt::UserRole, i); // 把枚举的索引(模块ID)存储在 UserRole 中 listWidget->addItem(item); } layout->addWidget(listWidget); // 创建水平布局,用于存放确认和取消按钮 QHBoxLayout* buttonLayout = new QHBoxLayout(); QPushButton* confirmButton = new QPushButton(tr("Confirm", "确定"), &dialog); buttonLayout->addWidget(confirmButton); QPushButton* cancelButton = new QPushButton(tr("Cancel", "取消"), &dialog); buttonLayout->addWidget(cancelButton); layout->addLayout(buttonLayout); // 禁用对话框的关闭按钮,强制用户选择 dialog.setWindowFlag(Qt::WindowCloseButtonHint, false); // 确认按钮点击事件 connect(confirmButton, &QPushButton::clicked, &dialog, &QDialog::accept); // 取消按钮点击事件 connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject); // 显示对话框 if (dialog.exec() == QDialog::Accepted) { QList selectedItems = listWidget->selectedItems(); if (selectedItems.isEmpty()) { JMessageTip::Message_warning(tr("Error !", "错误!"), tr("Please select a module!", "请选择一个模组!"), this); return; } // 通过 UserRole 获取选择的模块 ID int selectedModuleIndex = selectedItems.first()->data(Qt::UserRole).toInt(); // 根据选中的模块索引创建策略 MODULE_LIST moduleType = static_cast(selectedModuleIndex); UINT newStrategyId = 0; LONG ret = m_CamerAndLamp->CreatePrStrategy(moduleType, newStrategyId); if (ret == S_OK) { // 如果策略创建成功,获取新策略对象 PR_STRATEGY* newPrStrategy = m_manageDB->GetCProduct()->GetPrStrategy(newStrategyId); if (newPrStrategy) { // 将新策略添加到 m_vecPrStrategy 中 m_vecPrStrategy.push_back(*newPrStrategy); int vectorIndex = int(m_vecPrStrategy.size()) - 1; AddPrStrategyPage(vectorIndex, m_vecPrStrategy[vectorIndex]); // 如果需要进一步操作,比如更新 UI 或者做其他任务 //JMessageTip::Message_information(tr("Success!", "成功 !"), tr("Strategy created and added successfully!"), this); m_StrategyOrTemplateChanged = true; //QTSignalSlotManager::get_instance()->SendSignalUpdateBondMatrixTemplateID(1, newStrategyId); } else { JMessageTip::Message_warning(tr("Error!","错误"), tr("Failed to retrieve strategy after creation","创建后检索策略失败")); } } else { JMessageTip::Message_warning(tr("Error!","错误"), tr("Failed to create strategyn","创建策略失败")); } } else { JMessageTip::Message_information(tr("Operation Canceled!","操作已取消!"), tr("The operation was canceled","操作已取消"), this); } } void TemplateProgramPage::onDeleteStrategyClicked() { // Step 1: Check if the strategy is selected if (!curentPrStrategy) { JMessageTip::Message_warning(tr("Error !", "错误!"), tr("No strategy selected!", "没有选择策略!"), this); return; } // Step 2: Confirm deletion of strategy QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Delete Strategy","删除策略"), tr("Are you sure you want to delete this strategy and its associated templates?","您确定要删除此策略及其关联的模板吗?"), QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::No) { return; // User canceled the deletion } // Step 3: Iterate through the templates associated with the current strategy and delete them for (const auto& templateStruct : curentPrStrategy->vecTemplateId) { int templateId = templateStruct.iTemplateId; QWidget* templateWidget = m_mapIndexPrTemplateWidget.value(templateId, nullptr); if (templateWidget) { // Remove the template from the map m_mapPrTemplateWidgetIndex.remove(templateWidget); m_mapIndexPrTemplateWidget.remove(templateId); // Delete the template widget from the UI delete templateWidget; // This will delete the widget and remove it from the layout // Delete the template from the database m_manageDB->GetCProduct()->DeletePrTemplate(templateId); // Update local cache and remove template from the strategy's list DeletePrTemplate(templateId); // Remove the template from the strategy's template list auto it = std::remove_if(curentPrStrategy->vecTemplateId.begin(), curentPrStrategy->vecTemplateId.end(), [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; }); curentPrStrategy->vecTemplateId.erase(it, curentPrStrategy->vecTemplateId.end()); } } // Step 4: Delete the strategy itself int strategyId = curentPrStrategy->iStrategyId; // Remove the strategy from the map QWidget* strategyWidget = m_mapIndexPrStrategyWidget.value(strategyId, nullptr); if (strategyWidget) { m_mapPrStrategyWidgetIndex.remove(strategyWidget); m_mapIndexPrStrategyWidget.remove(strategyId); // Delete the strategy widget from the UI delete strategyWidget; } // Step 5: Remove the strategy from the database and local data structure m_manageDB->GetCProduct()->DeleteStrategy(strategyId); DeleteStrategy(strategyId); // Step 6: Remove the associated tab page for the strategy from the QTabWidget for (int i = 0; i < ui.tabWidget->count(); ++i) { if (ui.tabWidget->tabText(i) == QString(tr("Stra %1","PR策略 %1")).arg(strategyId)) { ui.tabWidget->removeTab(i); // Remove the tab associated with the strategy break; } } // Step 7: Clear the current strategy curentPrStrategy = nullptr; m_currentSelectedWidget = nullptr; // Step 8: Refresh the UI to reflect the changes refreshCurrentTabLayout(); // Step 9: Show success message //JMessageTip::Message_information(tr("Success!"), tr("Strategy and associated templates deleted successfully!"), this); } void TemplateProgramPage::onAddTemplateClicked() { // 1) 取当前选中的策略索引 int stratIndex = ui.tabWidget->currentIndex(); if (!curentPrStrategy) { JMessageTip::Message_warning(tr("Error !", "错误!"), tr("No strategy selected!", "没有选择策略!"),this); return; } vector _cameraIdList = m_CamerAndLamp->GetCameraIdList(MODULE_LIST(curentPrStrategy->iModuleType)); // 2) 如果相机列表只有一个,直接创建模板,否则弹出相机选择对话框 if (_cameraIdList.size() == 1) { // 直接使用唯一相机 CreateTemplate(_cameraIdList[0].iCameraId, stratIndex); } else { // 弹出相机选择对话框 QDialog dialog(this); dialog.setWindowTitle(tr("Please Chose Camera", "请选择相机")); QVBoxLayout* layout = new QVBoxLayout(&dialog); QListWidget* listWidget = new QListWidget(&dialog); // 填充相机 ID 列表 for (const CameraInfo& cam : _cameraIdList) { QListWidgetItem* item = new QListWidgetItem(QString::fromLocal8Bit(cam.name.c_str())); item->setData(Qt::UserRole, cam.iCameraId); // 把相机ID作为附加数据存进去 listWidget->addItem(item); } layout->addWidget(listWidget); // 创建一个水平布局,用于存放按钮 QHBoxLayout* buttonLayout = new QHBoxLayout(); // 确认按钮 QPushButton* confirmButton = new QPushButton(tr("Confirm", "确定"), &dialog); buttonLayout->addWidget(confirmButton); // 取消按钮 QPushButton* cancelButton = new QPushButton(tr("Cancel", "取消"), &dialog); buttonLayout->addWidget(cancelButton); // 将水平布局添加到垂直布局中 layout->addLayout(buttonLayout); // 禁用对话框的关闭按钮,强制用户选择 dialog.setWindowFlag(Qt::WindowCloseButtonHint, false); // 确认按钮点击事件 connect(confirmButton, &QPushButton::clicked, &dialog, &QDialog::accept); // 取消按钮点击事件 connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject); // 显示对话框 if (dialog.exec() == QDialog::Accepted) { QList selectedItems = listWidget->selectedItems(); if (selectedItems.isEmpty()) { JMessageTip::Message_warning(tr("Error !", "错误!"), tr("Please select a camera !","请选择一个相机 !"), this); return; } // 通过 UserRole 获取对应的相机 ID UINT _choseCameraId = selectedItems.first()->data(Qt::UserRole).toUInt(); // 创建模板 CreateTemplate(_choseCameraId, stratIndex); } else { // 用户点击取消按钮,关闭对话框并不执行任何操作 JMessageTip::Message_information(("Operation Canceled !","操作已取消"), tr("The operation was canceled !","操作已取消!"), this); } } } // 封装模板创建的逻辑 LONG TemplateProgramPage::CreateTemplate(UINT _choseCameraId, int stratIndex) { // 1) 调接口,创建新模板 UINT newTplId = 0; LONG ret = m_CamerAndLamp->CreatePrTemplate(MODULE_LIST(curentPrStrategy->iModuleType), _choseCameraId, newTplId); if (ret != OK) { JMessageTip::Message_warning(tr("Error !", "错误!"), tr("Cannot create template !", "创建模板失败 !"), this); return FAIL; } // 2) 从数据库缓存中取回完整的 PR_TEMPLATE 对象 PR_TEMPLATE* prTpl = m_pProduct->GetPrTemplate(newTplId); m_vecPrTemplate.push_back(*prTpl); int vectorIndex = int(m_vecPrTemplate.size()) - 1; // 3) 把它插入到策略的数据结构里 MULTI_TEMP_STRUCT mts; mts.iTemplateId = newTplId; mts.eResultSelect = prTpl->eResultSelect; curentPrStrategy->vecTemplateId.push_back(mts); bool _falg = m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); //4) 调 AddPrTemplatePage 创建那个行 widget AddPrTemplatePage(vectorIndex, m_vecPrTemplate[vectorIndex]); //5) 既然这是当前页,就把它加到 Tab 的布局里 QWidget* pageWidget = ui.tabWidget->widget(stratIndex); auto* vlay = qobject_cast(pageWidget->layout()); if (vlay) { // 插在最后一个 stretch 之前 vlay->insertWidget(vlay->count(), m_mapIndexPrTemplateWidget.value(newTplId)); } //6) 自动滚动到新添加的模板 m_StrategyOrTemplateChanged = true; return OK; } void TemplateProgramPage::AddPrStrategyPage(int vectorIndex, _PR_STRATEGY prStrategy) { //所有的都显示 QVector vecControls; QWidget* outWidget = new QWidget(); QGridLayout* prStrategyGridLayout = new QGridLayout(); prStrategyGridLayout->setSpacing(4); prStrategyGridLayout->setObjectName(QString::fromUtf8("prStrategy GridLayout")); prStrategyGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0 QGridLayout* boxGridLayout = new QGridLayout(); boxGridLayout->setSpacing(4); boxGridLayout->setObjectName(QString::fromUtf8("Box GridLayout")); boxGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0 QHBoxLayout* buttonLayout = new QHBoxLayout(); QSpacerItem* item = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); buttonLayout->addSpacerItem(item); QGroupBox* groupBox = new QGroupBox(outWidget); groupBox->setLayout(boxGridLayout); QGridLayout* matrixGridLayout = new QGridLayout(); matrixGridLayout->setSpacing(4); matrixGridLayout->setObjectName(QString::fromUtf8("matrixGridLayout")); matrixGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0 // Add matrix title QLabel* labelTitle = new QLabel(outWidget); labelTitle->setObjectName(QString::fromUtf8("labelTitle")); //labelTitle->setText(tr("PrStrategy: ") + QString::number(vectorIndex + 1)); labelTitle->setText(tr("StrategyID:","PR策略ID:") + QString::number(prStrategy.iStrategyId)); labelTitle->setStyleSheet("color: #6A78FF;height: 30px"); matrixGridLayout->addWidget(labelTitle, 0, 0, 1, 1); vecControls.push_back(labelTitle); // Add Date QLabel* labelDate = new QLabel(outWidget); labelDate->setObjectName(QString::fromUtf8("labelDate")); labelDate->setText(tr("Date:","日期:") + QString::fromStdString(prStrategy.Date)); matrixGridLayout->addWidget(labelDate, 0, 1, 1, 6); vecControls.push_back(labelDate); // Add Delete button //QPushButton* pushButtonDelete = new QPushButton(outWidget); //pushButtonDelete->setObjectName(QString::fromUtf8("button delete")); //pushButtonDelete->setText(tr("Dl")); //matrixGridLayout->addWidget(pushButtonDelete, 0, 8, 1, 1); //connect(pushButtonDelete, &QPushButton::clicked, this, [=]() { // //处理index // auto currentIt = m_mapPrStrategyWidgetIndex.find(outWidget); // int index = currentIt.value(); //迭代器 erase后currentIt被删除了 // m_mapPrStrategyWidgetIndex.erase(currentIt); // delete outWidget; // }); //// Add button 1 //QPushButton* pushButton1 = new QPushButton(outWidget); //pushButton1->setObjectName(QString::fromUtf8("button 1")); //pushButton1->setText(tr("b1")); //matrixGridLayout->addWidget(pushButton1, 0, 2, 1, 1); //// Add button 2 //QPushButton* pushButton2 = new QPushButton(outWidget); //pushButton2->setObjectName(QString::fromUtf8("button 2")); //pushButton2->setText(tr("b2")); //matrixGridLayout->addWidget(pushButton2, 0, 3, 1, 1); //// Add button 3 //QPushButton* pushButton3 = new QPushButton(outWidget); //pushButton3->setObjectName(QString::fromUtf8("button 3")); //pushButton3->setText(tr("b3")); //matrixGridLayout->addWidget(pushButton3, 0, 4, 1, 1); //// Add button 4 //QPushButton* pushButton4 = new QPushButton(outWidget); //pushButton4->setObjectName(QString::fromUtf8("button 4")); //pushButton4->setText(tr("b4")); //matrixGridLayout->addWidget(pushButton4, 0, 5, 1, 1); //// Add button 5 //QPushButton* pushButton5 = new QPushButton(outWidget); //pushButton5->setObjectName(QString::fromUtf8("button 5")); //pushButton5->setText(tr("b5")); //matrixGridLayout->addWidget(pushButton5, 0, 6, 1, 1); //// Add button 6 //QPushButton* pushButton6 = new QPushButton(outWidget); //pushButton6->setObjectName(QString::fromUtf8("button 6")); //pushButton6->setText(tr("b6")); //matrixGridLayout->addWidget(pushButton6, 0, 7, 1, 1); //// Add button 7 //QPushButton* pushButton7 = new QPushButton(outWidget); //pushButton7->setObjectName(QString::fromUtf8("button 7")); //pushButton7->setText(tr("b7")); //matrixGridLayout->addWidget(pushButton7, 0, 8, 1, 1); //// Add ID //QLabel* labelPrStrategyID = new QLabel(outWidget); //labelPrStrategyID->setObjectName(QString::fromUtf8("labelPrStrategyID")); //labelPrStrategyID->setText(tr("PrStrategyID")); //matrixGridLayout->addWidget(labelPrStrategyID, 1, 0, 1, 1); //vecControls.push_back(labelPrStrategyID); //SpinBox* spinBoxPrStrategyID = new SpinBox(outWidget); //spinBoxPrStrategyID->setObjectName(QString::fromUtf8("spinBoxPrStrategyID")); //spinBoxPrStrategyID->setFixedWidth(95); // Set fixed width to 95 //matrixGridLayout->addWidget(spinBoxPrStrategyID, 1, 1, 1, 1); //vecControls.push_back(spinBoxPrStrategyID); //XYR ////替换 DoubleSpinBox 为 QLabel //QLabel* labelPrStrategyXY = new QLabel(outWidget); //labelPrStrategyXY->setObjectName(QString::fromUtf8("labelPrStrategyXY")); //labelPrStrategyXY->setText(tr("ReferPos ")); // 参考点 //matrixGridLayout->addWidget(labelPrStrategyXY, 2, 0, 1, 1); //vecControls.push_back(labelPrStrategyXY); //// RefX //QLabel* labelRefX = new QLabel(outWidget); //labelRefX->setObjectName(QString::fromUtf8("labelRefX")); //labelRefX->setText(tr("X:")); // 显示 prStrategy.stRef.x //matrixGridLayout->addWidget(labelRefX, 2, 1, 1, 1); //vecControls.push_back(labelRefX); ////QLabel* labelRefXData = new QLabel(outWidget); ////labelRefXData->setObjectName(QString::fromUtf8("labelRefXData")); ////labelRefXData->setText(QString::number(prStrategy.stRef.x)); // 显示 prStrategy.stRef.x ////matrixGridLayout->addWidget(labelRefXData, 2, 2, 1, 3); ////vecControls.push_back(labelRefXData); //// RefY //QLabel* labelRefY = new QLabel(outWidget); //labelRefY->setObjectName(QString::fromUtf8("labelRefY")); //labelRefY->setText(tr("Y:")); // 显示 prStrategy.stRef.y //matrixGridLayout->addWidget(labelRefY, 2, 5, 1, 1); //vecControls.push_back(labelRefY); ////QLabel* labelRefYData = new QLabel(outWidget); ////labelRefYData->setObjectName(QString::fromUtf8("labelRefYData")); ////labelRefYData->setText(tr("Y: ") + QString::number(prStrategy.stRef.y)); // 显示 prStrategy.stRef.y ////matrixGridLayout->addWidget(labelRefYData, 2, 6, 1, 3); ////vecControls.push_back(labelRefYData); //// Angle //QLabel* labelRefAngle = new QLabel(outWidget); //labelRefAngle->setObjectName(QString::fromUtf8("labelRefAngle")); //labelRefAngle->setText(tr("Angle:")); //matrixGridLayout->addWidget(labelRefAngle, 2, 9, 1, 2); //vecControls.push_back(labelRefAngle); //QLabel* labelRefAngleData = new QLabel(outWidget); //labelRefAngleData->setObjectName(QString::fromUtf8("labelRefAngleData")); //labelRefAngleData->setText(tr("Angle: ") + QString::number(prStrategy.stRef.a)); //matrixGridLayout->addWidget(labelRefAngleData, 2, 9, 2, 2); //vecControls.push_back(labelRefAngleData);*/ //DoubleSpinBox* doubleSpinBoxRefX = new DoubleSpinBox(outWidget); //doubleSpinBoxRefX->setObjectName(QString::fromUtf8("doubleSpinBoxRefX")); ////doubleSpinBoxRefX->setFixedWidth(106); // Set fixed width to 95 //matrixGridLayout->addWidget(doubleSpinBoxRefX, 2, 2, 1, 3); //vecControls.push_back(doubleSpinBoxRefX); //DoubleSpinBox* doubleSpinBoxRefY = new DoubleSpinBox(outWidget); //doubleSpinBoxRefY->setObjectName(QString::fromUtf8("doubleSpinBoxRefY")); ////doubleSpinBoxRefY->setFixedWidth(106); // Set fixed width to 95 //matrixGridLayout->addWidget(doubleSpinBoxRefY, 2, 6, 1, 3); //vecControls.push_back(doubleSpinBoxRefY); //DoubleSpinBox* doubleSpinBoxRefA = new DoubleSpinBox(outWidget); //doubleSpinBoxRefA->setObjectName(QString::fromUtf8("doubleSpinBoxRefA")); ////doubleSpinBoxRefA->setFixedWidth(106); // Set fixed width to 95 //matrixGridLayout->addWidget(doubleSpinBoxRefA, 2, 9, 1, 2); //vecControls.push_back(doubleSpinBoxRefA); //QLabel* labelPrStrategyAngle = new QLabel(outWidget); //labelPrStrategyAngle->setObjectName(QString::fromUtf8("labelPrStrategyAngle")); //labelPrStrategyAngle->setText(tr("Angle")); //matrixGridLayout->addWidget(labelPrStrategyAngle, 3, 0, 1, 1); //vecControls.push_back(labelPrStrategyAngle); //// 替换 DoubleSpinBox 为 QLabel 显示 RefA //QLabel* labelRefA = new QLabel(outWidget); //labelRefA->setObjectName(QString::fromUtf8("labelRefA")); //labelRefA->setText(QString::number(prStrategy.stRef.a)); // 显示 prStrategy.stRef.a //matrixGridLayout->addWidget(labelRefA, 3, 1, 1, 4); //vecControls.push_back(labelRefA); QLabel* labelPrStrategyXY = new QLabel(outWidget); labelPrStrategyXY->setObjectName(QString::fromUtf8("labelPrStrategyXY")); labelPrStrategyXY->setText(tr("RefPos X&Y","参考位置:X&Y"));//参考点 matrixGridLayout->addWidget(labelPrStrategyXY, 2, 0, 1, 1); vecControls.push_back(labelPrStrategyXY); DoubleSpinBox* doubleSpinBoxRefX = new DoubleSpinBox(outWidget); doubleSpinBoxRefX->setObjectName(QString::fromUtf8("doubleSpinBoxRefX")); doubleSpinBoxRefX->setFixedWidth(130); // Set fixed width to 95 matrixGridLayout->addWidget(doubleSpinBoxRefX, 2, 1, 1, 4); vecControls.push_back(doubleSpinBoxRefX); DoubleSpinBox* doubleSpinBoxRefY = new DoubleSpinBox(outWidget); doubleSpinBoxRefY->setObjectName(QString::fromUtf8("doubleSpinBoxRefY")); doubleSpinBoxRefY->setFixedWidth(130); // Set fixed width to 95 matrixGridLayout->addWidget(doubleSpinBoxRefY, 2, 5, 1, 4); vecControls.push_back(doubleSpinBoxRefY); QLabel* labelPrStrategyAngle = new QLabel(outWidget); labelPrStrategyAngle->setObjectName(QString::fromUtf8("labelPrStrategyAngle")); labelPrStrategyAngle->setText(tr("Refpos Angle","参考角度")); matrixGridLayout->addWidget(labelPrStrategyAngle, 3, 0, 1, 1); vecControls.push_back(labelPrStrategyAngle); DoubleSpinBox* doubleSpinBoxRefA = new DoubleSpinBox(outWidget); doubleSpinBoxRefA->setObjectName(QString::fromUtf8("doubleSpinBoxRefA")); doubleSpinBoxRefA->setFixedWidth(130); // Set fixed width to 95 matrixGridLayout->addWidget(doubleSpinBoxRefA, 3, 1, 1, 4); vecControls.push_back(doubleSpinBoxRefA); doubleSpinBoxRefX->setValue(prStrategy.stRef.x); doubleSpinBoxRefX->setReadOnly(true); // 设置为只读,用户不能修改 doubleSpinBoxRefY->setValue(prStrategy.stRef.y); doubleSpinBoxRefY->setReadOnly(true); // 设置为只读,用户不能修改 doubleSpinBoxRefA->setValue(prStrategy.stRef.a); doubleSpinBoxRefA->setReadOnly(true); // 设置为只读,用户不能修改 //SpinBox* spinBoxDate = new SpinBox(outWidget); //spinBoxDate->setObjectName(QString::fromUtf8("spinBoxDate")); //spinBoxDate->setFixedWidth(95); // Set fixed width to 95 //matrixGridLayout->addWidget(spinBoxDate, 2, 2, 1, 1); //vecControls.push_back(spinBoxDate); QFrame* line = new QFrame(outWidget); line->setFrameShape(QFrame::NoFrame); // 移除默认框架 line->setFixedHeight(2); // 设置固定高度 line->setStyleSheet("background-color: #C7CAEB;"); boxGridLayout->addLayout(matrixGridLayout, 2, 0); boxGridLayout->addWidget(line); //prStrategyGridLayout->addLayout(buttonLayout, 1, 0); prStrategyGridLayout->addWidget(groupBox); outWidget->setLayout(prStrategyGridLayout); outWidget->setStyleSheet(""); ui.verticalLayoutStrategy->addWidget(outWidget); ui.verticalLayoutStrategy->setContentsMargins(0, 0, 0, 0); // Adjust margins if necessary ui.verticalLayoutStrategy->setAlignment(Qt::AlignTop | Qt::AlignLeft); // Align the layout to the top-left m_mapPrStrategyWidgetIndex.insert(outWidget, prStrategy.iStrategyId); m_mapIndexPrStrategyWidget.insert(prStrategy.iStrategyId, outWidget); // 点击时的操作 outWidget->installEventFilter(this); //connect(spinBoxRow, &SpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].BondMatrixRow = spinBoxRow->value(); // }); //connect(spinBoxCol, &SpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].BondMatrixCol = spinBoxCol->value(); // }); //connect(doubleSpinBoxLeftTopX, &DoubleSpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].LeftTopPoint.x = doubleSpinBoxLeftTopX->value(); // }); //connect(doubleSpinBoxLeftTopY, &DoubleSpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].LeftTopPoint.y = doubleSpinBoxLeftTopY->value(); // }); //connect(doubleSpinBoxRightTopX, &DoubleSpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].RightTopPoint.x = doubleSpinBoxRightTopX->value(); // }); //connect(doubleSpinBoxRightTopY, &DoubleSpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].RightTopPoint.y = doubleSpinBoxRightTopY->value(); // }); //connect(doubleSpinBoxRightButtomX, &DoubleSpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].RightBottomPoint.x = doubleSpinBoxRightButtomX->value(); // }); //connect(doubleSpinBoxRightButtomY, &DoubleSpinBox::editDone, this, [=]() { // m_vectBondMatrixs[vectorIndex].RightBottomPoint.y = doubleSpinBoxRightButtomY->value(); // }); //connect(lineEditNoBondPts, &QLineEdit::textChanged, this, [=]() { // }); } void TemplateProgramPage::UpdatePrStrategyUI() { if (!curentPrStrategy) { return; // 如果没有当前策略,不做更新 } // 获取当前策略ID int strategyId = curentPrStrategy->iStrategyId; // 更新策略ID显示 if (m_mapIndexPrStrategyWidget.contains(strategyId)) { QWidget* outWidget = m_mapIndexPrStrategyWidget.value(strategyId); // 更新策略ID标签 QLabel* labelTitle = outWidget->findChild("labelTitle"); if (labelTitle) { labelTitle->setText(tr("StrategyID: ","策略id:") + QString::number(curentPrStrategy->iStrategyId)); } // 更新日期标签 QLabel* labelDate = outWidget->findChild("labelDate"); if (labelDate) { labelDate->setText(tr("Date: ","日起:") + QString::fromStdString(curentPrStrategy->Date)); } // 更新参考点位置X和Y DoubleSpinBox* doubleSpinBoxRefX = outWidget->findChild("doubleSpinBoxRefX"); if (doubleSpinBoxRefX) { doubleSpinBoxRefX->setValue(curentPrStrategy->stRef.x); doubleSpinBoxRefX->setReadOnly(true); // 设置为只读 } DoubleSpinBox* doubleSpinBoxRefY = outWidget->findChild("doubleSpinBoxRefY"); if (doubleSpinBoxRefY) { doubleSpinBoxRefY->setValue(curentPrStrategy->stRef.y); doubleSpinBoxRefY->setReadOnly(true); // 设置为只读 } DoubleSpinBox* doubleSpinBoxRefA = outWidget->findChild("doubleSpinBoxRefA"); if (doubleSpinBoxRefA) { doubleSpinBoxRefA->setValue(curentPrStrategy->stRef.a); doubleSpinBoxRefA->setReadOnly(true); // 设置为只读 } } } void TemplateProgramPage::updateComboBox(UINT currentStrategyId) { // 清空下拉框 ui.comboBoxCurStrategy->clear(); // 填充所有策略的ID for (const auto& strategy : m_vecPrStrategy) { ui.comboBoxCurStrategy->addItem(QString::number(strategy.iStrategyId)); } // 将当前策略ID设置为选中项 ui.comboBoxCurStrategy->setCurrentText(QString::number(currentStrategyId)); } void TemplateProgramPage::AddPrTemplatePage(int vectorIndex, PR_TEMPLATE& prTemplate) { //全部添加进去后,只显示当前PrStrategy的PrTemplate QVector vecControls; QWidget* outWidget = new QWidget(); QGridLayout* prStrategyGridLayout = new QGridLayout(); prStrategyGridLayout->setSpacing(2); prStrategyGridLayout->setObjectName(QString::fromUtf8("prStrategy GridLayout")); prStrategyGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0 QGridLayout* boxGridLayout = new QGridLayout(); boxGridLayout->setSpacing(2); boxGridLayout->setObjectName(QString::fromUtf8("Box GridLayout")); boxGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0 QHBoxLayout* buttonLayout = new QHBoxLayout(); QSpacerItem* item = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); buttonLayout->addSpacerItem(item); QGroupBox* groupBox = new QGroupBox(outWidget); groupBox->setLayout(boxGridLayout); QGridLayout* matrixGridLayout = new QGridLayout(); matrixGridLayout->setSpacing(2); matrixGridLayout->setObjectName(QString::fromUtf8("matrixGridLayout")); matrixGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0 // Add matrix title QLabel* labelTitle = new QLabel(outWidget); labelTitle->setObjectName(QString::fromUtf8("labelTitle")); //labelTitle->setText(tr("PrStrategy: ") + QString::number(vectorIndex + 1)); labelTitle->setText(tr("TempID: ", "模板ID: ") + QString::number(prTemplate.iTemplateId)); labelTitle->setStyleSheet("color: #6A78FF;height: 30px"); matrixGridLayout->addWidget(labelTitle, 0, 0, 1, 1); vecControls.push_back(labelTitle); // Add Date QLabel* labelDate = new QLabel(outWidget); labelDate->setObjectName(QString::fromUtf8("labelDate")); labelDate->setText(tr("Date: ", "日期: ")+ QString::fromStdString(prTemplate.Date)); matrixGridLayout->addWidget(labelDate, 0, 1, 1, 6); vecControls.push_back(labelDate); //QLineEdit* lineEditDate = new QLineEdit(outWidget); //lineEditDate->setObjectName(QString::fromUtf8("lineEditDate")); //matrixGridLayout->addWidget(lineEditDate, 0, 1, 1, 6); //vecControls.push_back(lineEditDate); //lineEditDate->setReadOnly(true); //lineEditDate->setCursor(Qt::PointingHandCursor); //lineEditDate->setProperty("vectorIndex", vectorIndex); // 存储索引 //lineEditDate->setProperty("parentMatrixIndex", -1); // 设置父矩阵的索引 //lineEditDate->installEventFilter(this); // Add Delete Out Matrix button QPushButton* pushButtonDelete = new QPushButton(outWidget); pushButtonDelete->setObjectName(QString::fromUtf8("button delete")); pushButtonDelete->setToolTip(tr("DeleteTemplate", "删除模板")); // 设置鼠标悬停时显示的文字提示 pushButtonDelete->setIcon(QIcon(":/images/Program/deleteInner.png")); //pushButtonDelete->setText(tr("Dl")); matrixGridLayout->addWidget(pushButtonDelete, 0, 7, 1, 1); connect(pushButtonDelete, &QPushButton::clicked, this, [=]() { //处理index //auto currentIt = m_mapPrTemplateWidgetIndex.find(outWidget); //int index = currentIt.value(); //迭代器 erase后currentIt被删除了 ////删除Map //m_mapPrTemplateWidgetIndex.erase(currentIt); // 1) 先拿到这个 widget 对应的 templateId if (!m_mapPrTemplateWidgetIndex.contains(outWidget)) return; // 防御,万一映射里没它 int templateId = m_mapPrTemplateWidgetIndex.value(outWidget); // 2) 从两张表里都移除 m_mapPrTemplateWidgetIndex.remove(outWidget); m_mapIndexPrTemplateWidget.remove(templateId); //调接口删除数据 m_manageDB->GetCProduct()->DeletePrTemplate(templateId); //更新本地缓存 DeletePrTemplate(templateId); //m_vecPrStrategy = m_manageDB->GetCProduct()->GetPrStrategy(); for (auto it = curentPrStrategy->vecTemplateId.begin(); it != curentPrStrategy->vecTemplateId.end(); ++it) { if (it->iTemplateId == templateId) { curentPrStrategy->vecTemplateId.erase(it); break; // 删除完一个后退出循环 } } //更新DB缓存 m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); //删除布局 delete outWidget; m_StrategyOrTemplateChanged = true; }); //// Add button 1 //QPushButton* pushButton1 = new QPushButton(outWidget); //pushButton1->setObjectName(QString::fromUtf8("button 1")); //pushButton1->setText(tr("b1")); //matrixGridLayout->addWidget(pushButton1, 0, 6, 1, 1); // button 2 QPushButton* buttonMoveForward = new QPushButton(outWidget); buttonMoveForward->setObjectName(QString::fromUtf8("buttonMoveForward")); buttonMoveForward->setText(QString::fromLocal8Bit("↑"));//⇑ buttonMoveForward->setToolTip(tr("MoveForward", "前移")); // 设置鼠标悬停时显示的文字提示 matrixGridLayout->addWidget(buttonMoveForward, 1, 7, 1, 1); // button 3 QPushButton* buttonMoveBack = new QPushButton(outWidget); buttonMoveBack->setObjectName(QString::fromUtf8("buttonMoveBack")); buttonMoveBack->setText(QString::fromLocal8Bit("↓"));//⇓ buttonMoveBack->setToolTip(tr("MoveBack", "后移")); // 设置鼠标悬停时显示的文字提示 matrixGridLayout->addWidget(buttonMoveBack, 2, 7, 1, 1); // button 4 QPushButton* buttonEdit = new QPushButton(outWidget); buttonEdit->setObjectName(QString::fromUtf8("buttonEdit")); buttonEdit->setToolTip(tr("EditTemplate", "编辑模板")); // 设置鼠标悬停时显示的文字提示 //buttonEdit->setText(tr("Ed")); buttonEdit->setIcon(QIcon(":/images/Program/editTemplate.png")); matrixGridLayout->addWidget(buttonEdit, 3, 7, 1, 1); // button MoveTo QPushButton* pushButtonMoveToXYZR = new QPushButton(outWidget); pushButtonMoveToXYZR->setObjectName(QString::fromUtf8("pushButtonMoveToXYZR")); pushButtonMoveToXYZR->setToolTip(tr("MoveToGrabPos", "移动到拍照位置")); // 设置鼠标悬停时显示的文字提示 pushButtonMoveToXYZR->setIcon(QIcon(":/images/Program/moveTo.png")); matrixGridLayout->addWidget(pushButtonMoveToXYZR, 4, 7, 1, 1); connect(pushButtonMoveToXYZR, &QPushButton::clicked, this, [=]() { bool reply = JMessageTip::Message_question(tr("Confirmation", "确认操作"), tr("Are all the axes confirmed to have moved to the template position ?", "确定所有轴移动到模板位置?"), this); if (reply) TemplateMoveToXYZRAxisPosition(prTemplate.iModuleType, prTemplate.stGrabPos); }); //灯光 QPushButton* pushButtonAllLight = new QPushButton(outWidget); pushButtonAllLight->setObjectName(QString::fromUtf8("pushButtonAllLight")); pushButtonAllLight->setToolTip(tr("SetAllLight", "设置所有灯光")); // 设置鼠标悬停时显示的文字提示 pushButtonAllLight->setText(QString::fromLocal8Bit("L")); matrixGridLayout->addWidget(pushButtonAllLight, 0, 8, 1, 1); connect(pushButtonAllLight, &QPushButton::clicked, this, [=]() { //QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Confirmation", "确认操作"), tr("Are you sure you want to change the lighting settings?", "是否确定修改灯光设置?"), QMessageBox::Yes | QMessageBox::No); //if (reply == QMessageBox::Yes) { m_CamerAndLamp->SetRedLight(prTemplate.iCameraId, prTemplate.iRedLight); m_CamerAndLamp->SetBlueLight(prTemplate.iCameraId, prTemplate.iBlueLight); m_CamerAndLamp->SetGreenLight(prTemplate.iCameraId, prTemplate.iBlueLight); m_CamerAndLamp->SetPointLight(prTemplate.iCameraId, prTemplate.iPointLight); } }); // button TakePhoto QPushButton* pushButtonTakePhoto = new QPushButton(outWidget); pushButtonTakePhoto->setObjectName(QString::fromUtf8("pushButtonTakePhoto")); pushButtonTakePhoto->setText(QString::fromLocal8Bit("TP")); pushButtonTakePhoto->setToolTip(tr("TakePhoto", "拍照")); // 设置鼠标悬停时显示的文字提示 matrixGridLayout->addWidget(pushButtonTakePhoto, 1, 8, 1, 1); // button 4 QPushButton* pushButtonBlueLight = new QPushButton(outWidget); pushButtonBlueLight->setObjectName(QString::fromUtf8("pushButtonBlueLight")); pushButtonBlueLight->setText(tr("bt1")); matrixGridLayout->addWidget(pushButtonBlueLight, 2, 8, 1, 1); // button 5 QPushButton* pushButtonPointLight = new QPushButton(outWidget); pushButtonPointLight->setObjectName(QString::fromUtf8("pushButtonPointLight")); pushButtonPointLight->setText(tr("bt2")); matrixGridLayout->addWidget(pushButtonPointLight, 3, 8, 1, 1); // button 5 QPushButton* pushButton5 = new QPushButton(outWidget); pushButton5->setObjectName(QString::fromUtf8("button 5")); pushButton5->setText(tr("b5")); matrixGridLayout->addWidget(pushButton5, 4, 8, 1, 1); connect(buttonMoveForward, &QPushButton::clicked, this, [this, outWidget]() { onMoveTemplate(outWidget, /*MoveForward=*/true); }); connect(buttonMoveBack, &QPushButton::clicked, this, [this, outWidget]() { onMoveTemplate(outWidget, /*MoveForward=*/false); }); connect(buttonEdit, &QPushButton::clicked, this, [=]() { // 调用 ModifyBondMatrixTemplate 函数 if (m_pTemplateCViewInterface) { m_pTemplateCViewInterface->GetViewMatrix()->ModifyBondMatrixTemplate(prTemplate.iTemplateId); } }); // CameraID QLabel* labelCameraID = new QLabel(outWidget); labelCameraID->setObjectName(QString::fromUtf8("labelCameraID")); labelCameraID->setText(tr("CameraID", "相机ID: ")); matrixGridLayout->addWidget(labelCameraID, 1, 0, 1, 1); vecControls.push_back(labelCameraID); SpinBox* spinBoxCameraID = new SpinBox(outWidget); spinBoxCameraID->setObjectName(QString::fromUtf8("spinBoxDate")); //spinBoxCameraID->setFixedWidth(50); // Set fixed width to 95 matrixGridLayout->addWidget(spinBoxCameraID, 1, 1, 1, 2); vecControls.push_back(spinBoxCameraID); // TempResult QLabel* labelTempResult = new QLabel(outWidget); labelTempResult->setObjectName(QString::fromUtf8("labelTempResult")); labelTempResult->setText(tr("TempResult", "模板结果ID: ")); matrixGridLayout->addWidget(labelTempResult, 2, 0, 2, 1); vecControls.push_back(labelTempResult); // 1. X QCheckBox* checkX = new QCheckBox(outWidget); checkX->setObjectName(QString::fromUtf8("checkX")); checkX->setText(tr("X")); matrixGridLayout->addWidget(checkX, 2, 1, 1, 1); vecControls.push_back(checkX); // 2. AngleX QCheckBox* checkAngleX = new QCheckBox(outWidget); checkAngleX->setObjectName(QString::fromUtf8("checkAngleX")); checkAngleX->setText(tr("AngleX", "X角度")); matrixGridLayout->addWidget(checkAngleX, 2, 2, 1, 1); vecControls.push_back(checkAngleX); // 3. Y QCheckBox* checkY = new QCheckBox(outWidget); checkY->setObjectName(QString::fromUtf8("checkY")); checkY->setText(tr("Y")); matrixGridLayout->addWidget(checkY, 3, 1, 1, 1); vecControls.push_back(checkY); // 4. AngleY QCheckBox* checkAngleY = new QCheckBox(outWidget); checkAngleY->setObjectName(QString::fromUtf8("checkAngleY")); checkAngleY->setText(tr("AngleY", "Y角度")); matrixGridLayout->addWidget(checkAngleY, 3, 2, 1, 1); vecControls.push_back(checkAngleY); prTemplate.eResultSelect; // 根据 prTemplate.eResultSelect 初始化状态 checkX->setChecked(prTemplate.eResultSelect & OUT_X); checkY->setChecked(prTemplate.eResultSelect & OUT_Y); checkAngleX->setChecked(prTemplate.eResultSelect & OUT_Ax); checkAngleY->setChecked(prTemplate.eResultSelect & OUT_Ay); //auto bindResultSelectToggle = [this, outWidget](QCheckBox* check, // SEARCH_OUT bitMaskToSet, // SEARCH_OUT bitMaskToClear = static_cast(0)) //{ // connect(check, &QCheckBox::toggled, this, [this, outWidget, bitMaskToSet, bitMaskToClear](bool checked) { // // 1) 取出模板 ID // int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1); // if (templateId < 0) return; // // 2) 在 vector 里找到对应条目 // auto it = std::find_if(m_vecPrTemplate.begin(), // m_vecPrTemplate.end(), // [templateId](auto& pr) { return pr.iTemplateId == templateId; }); // if (it == m_vecPrTemplate.end()) return; // // 3) 更新 eResultSelect // int flags = int(it->eResultSelect); // if (checked) { // flags |= int(bitMaskToSet); // if (bitMaskToClear != 0) flags &= ~int(bitMaskToClear); // } // else { // flags &= ~int(bitMaskToSet); // } // it->eResultSelect = static_cast(flags); // }); //}; //// 然后把四个 connect 全部改成调用它: //bindResultSelectToggle(checkX, OUT_X); //bindResultSelectToggle(checkY, OUT_Y); //bindResultSelectToggle(checkAngleX, OUT_Ax, OUT_Ay); //bindResultSelectToggle(checkAngleY, OUT_Ay, OUT_Ax); // --- X 改变只负责更新 OUT_X 位 --- connect(checkX, &QCheckBox::toggled, this, [=](bool checked) { int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1); if (templateId < 0) return; auto it = std::find_if(m_vecPrTemplate.begin(), m_vecPrTemplate.end(), [templateId](auto& pr) { return pr.iTemplateId == templateId; }); if (it == m_vecPrTemplate.end()) return; auto m = static_cast(it->eResultSelect); if (checked) m |= OUT_X; else m &= ~OUT_X; it->eResultSelect = static_cast(m); // 更新 vecTemplateId 中对应的模板 auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(), curentPrStrategy->vecTemplateId.end(), [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; }); // 如果找到对应模板,更新它的 eResultSelect if (vecIt != curentPrStrategy->vecTemplateId.end()) { vecIt->eResultSelect = it->eResultSelect; } m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); m_vecPrTemplate[vectorIndex].eResultSelect; }); // --- Y 改变只负责更新 OUT_Y 位 --- connect(checkY, &QCheckBox::toggled, this, [=](bool checked) { int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1); if (templateId < 0) return; auto it = std::find_if(m_vecPrTemplate.begin(), m_vecPrTemplate.end(), [templateId](auto& pr) { return pr.iTemplateId == templateId; }); if (it == m_vecPrTemplate.end()) return; auto m = static_cast(it->eResultSelect); if (checked) m |= OUT_Y; else m &= ~OUT_Y; it->eResultSelect = static_cast(m); // 更新 vecTemplateId 中对应的模板 auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(), curentPrStrategy->vecTemplateId.end(), [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; }); // 如果找到对应模板,更新它的 eResultSelect if (vecIt != curentPrStrategy->vecTemplateId.end()) { vecIt->eResultSelect = it->eResultSelect; } m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); m_vecPrTemplate[vectorIndex].eResultSelect; }); // --- AngleX 勾上时取消 AngleY 并更新 OUT_Ax --- connect(checkAngleX, &QCheckBox::toggled, this, [=](bool checked) { int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1); if (templateId < 0) return; auto it = std::find_if(m_vecPrTemplate.begin(), m_vecPrTemplate.end(), [templateId](auto& pr) { return pr.iTemplateId == templateId; }); if (it == m_vecPrTemplate.end()) return; int m = int(it->eResultSelect); if (checked) { QSignalBlocker b(checkAngleY); checkAngleY->setChecked(false); m &= ~OUT_Ay; // ← 清除 Ay 位 m |= OUT_Ax; // 设置 Ax 位 } else { m &= ~OUT_Ax; // 取消 Ax 位 } it->eResultSelect = static_cast(m); // 更新 vecTemplateId 中对应的模板 auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(), curentPrStrategy->vecTemplateId.end(), [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; }); // 如果找到对应模板,更新它的 eResultSelect if (vecIt != curentPrStrategy->vecTemplateId.end()) { vecIt->eResultSelect = it->eResultSelect; } m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); m_vecPrTemplate[vectorIndex].eResultSelect; }); // --- AngleY 勾上时取消 AngleX 并更新 OUT_Ay --- connect(checkAngleY, &QCheckBox::toggled, this, [=](bool checked) { int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1); if (templateId < 0) return; auto it = std::find_if(m_vecPrTemplate.begin(), m_vecPrTemplate.end(), [templateId](auto& pr) { return pr.iTemplateId == templateId; }); if (it == m_vecPrTemplate.end()) return; int m = int(it->eResultSelect); if (checked) { QSignalBlocker b(checkAngleX); checkAngleX->setChecked(false); m &= ~OUT_Ax; // ← 清除 Ax 位 m |= OUT_Ay; // 设置 Ay 位 } else { m &= ~OUT_Ay; // 取消 Ay 位 } it->eResultSelect = static_cast(m); // 更新 vecTemplateId 中对应的模板 auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(), curentPrStrategy->vecTemplateId.end(), [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; }); // 如果找到对应模板,更新它的 eResultSelect if (vecIt != curentPrStrategy->vecTemplateId.end()) { vecIt->eResultSelect = it->eResultSelect; } m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); m_vecPrTemplate[vectorIndex].eResultSelect; }); // QLabel* labelPrMethod = new QLabel(outWidget); labelPrMethod->setObjectName(QString::fromUtf8("labelPrMethod")); labelPrMethod->setText(tr("PrMethod")); matrixGridLayout->addWidget(labelPrMethod, 4, 0, 1, 1); vecControls.push_back(labelPrMethod); SpinBox* spinBoxPrMethod = new SpinBox(outWidget); spinBoxPrMethod->setObjectName(QString::fromUtf8("spinBoxPrMethod")); //spinBoxPrMethod->setFixedWidth(50); // Set fixed width to 95 matrixGridLayout->addWidget(spinBoxPrMethod, 4, 1, 1, 2); vecControls.push_back(spinBoxPrMethod); JVision::ImageInfo imageInfo; if (m_CamerAndLamp->GetTemplateImage(prTemplate.iTemplateId, imageInfo) == OK) { // 1) 根据 ImageFormat 决定 QImage::Format QImage::Format qtFmt; int bytesPerLine = 0; switch (imageInfo.format) { case JVision::ImageFormat::GRAY8: qtFmt = QImage::Format_Grayscale8; bytesPerLine = imageInfo.width * 1; break; case JVision::ImageFormat::RGB888: qtFmt = QImage::Format_RGB888; bytesPerLine = imageInfo.width * 3; break; case JVision::ImageFormat::ARGB32: qtFmt = QImage::Format_ARGB32; bytesPerLine = imageInfo.width * 4; break; case JVision::ImageFormat::RGB32: // QImage::Format_RGB32 存储格式也是 0xffRRGGBB qtFmt = QImage::Format_RGB32; bytesPerLine = imageInfo.width * 4; break; case JVision::ImageFormat::YUV422: // 如果要支持 YUV422,这里需要先把 imageInfo.data 转成 RGB 或 ARGB // 比如用 OpenCV cv::cvtColor,或者自己写转换。 throw std::runtime_error("YUV422 尚未实现转换"); break; default: throw std::runtime_error("不支持的图像格式"); } // 2) 用原始内存构造 QImage — 注意这不会复制数据,所以后面要 copy() 一下或保证 data 的生命周期足够 QImage img(imageInfo.data, imageInfo.width, imageInfo.height, bytesPerLine, qtFmt); // 3) 如果 data 是 BGR 排序(而非 RGB),可以: // img = img.rgbSwapped(); // 4) 将 QImage 转为 QPixmap QPixmap pixmap = QPixmap::fromImage(img.copy()); // copy() 让 QPixmap 拷贝一份,后面可以安全 delete[] data // 5) 显示到 QLabel(跟原来的一样) QLabel* imageLabel = new QLabel(outWidget); imageLabel->setPixmap(pixmap.scaled(110, 110, Qt::KeepAspectRatio, Qt::SmoothTransformation)); imageLabel->setAlignment(Qt::AlignCenter); imageLabel->setFixedSize(110, 110); matrixGridLayout->addWidget(imageLabel, 1, 3, 4, 4); vecControls.push_back(imageLabel); imageLabel->installEventFilter(this); // Install event filter to catch click events on the label m_imageLabels.push_back(imageLabel); m_imagePixmaps.push_back(pixmap); // 6) 释放 ImageInfo 分配的内存 //delete[] imageInfo.data; } else { // 拿图失败处理…… } // Load the image //QString imagePath = "D:/config/db/Product1/2/ShapeMode.shm.jpg"; //QPixmap pixmap(imagePath); //// Create a QLabel to display the image in a smaller size //QLabel* imageLabel = new QLabel(outWidget); //imageLabel->setPixmap(pixmap.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); // Set size to 200x150, keeping aspect ratio //imageLabel->setAlignment(Qt::AlignCenter); // Align the image in the center of the label //imageLabel->setFixedSize(120, 120); // Set the maximum size for the image label //// Add the image label to the grid layout //matrixGridLayout->addWidget(imageLabel, 1, 3, 4, 4); // From row 1, column 2 to row 3, column 6 //vecControls.push_back(imageLabel); //// Connect click event for the image label //imageLabel->setCursor(Qt::PointingHandCursor); // Set cursor to hand to indicate clickability //imageLabel->installEventFilter(this); // Install event filter to catch click events on the label //// Store the QLabel and QPixmap for later use //m_imageLabels.push_back(imageLabel); //m_imagePixmaps.push_back(pixmap); QFrame* line = new QFrame(outWidget); line->setFrameShape(QFrame::NoFrame); // 移除默认框架 line->setFixedHeight(2); // 设置固定高度 line->setStyleSheet("background-color: #C7CAEB;"); boxGridLayout->addLayout(matrixGridLayout, 2, 0); boxGridLayout->addWidget(line); //prStrategyGridLayout->addLayout(buttonLayout, 1, 0); prStrategyGridLayout->addWidget(groupBox); outWidget->setLayout(prStrategyGridLayout); //ui.verticalLayoutTemplate->addWidget(outWidget); //ui.verticalLayoutTemplate->setContentsMargins(0, 0, 0, 0); // Adjust margins if necessary //ui.verticalLayoutTemplate->setAlignment(Qt::AlignTop | Qt::AlignLeft); // Align the layout to the top-left m_mapPrTemplateWidgetIndex.insert(outWidget, prTemplate.iTemplateId); m_mapIndexPrTemplateWidget.insert(prTemplate.iTemplateId, outWidget); spinBoxCameraID->setValue(prTemplate.iCameraId); spinBoxCameraID->setReadOnly(true); // 设置为只读,用户不能修改 //spinBoxTempResult->setValue(prTemplate.eResultSelect); //spinBoxTempResult->setReadOnly(true); // 设置为只读,用户不能修改 spinBoxPrMethod->setValue(prTemplate.iPrMethod); spinBoxPrMethod->setReadOnly(true); // 设置为只读,用户不能修改 //lineEditDate->setText(QString::fromStdString(prTemplate.Date)); //lineEditDate->setReadOnly(true); // 设置为只读,用户不能修改 } void TemplateProgramPage::TemplateMoveToXYZRAxisPosition(UINT iModuleType, X_Y_Z_R_STRUCT pos) { // 将 iModuleType 转换为对应的字符串 auto it = g_mapModuleList.find(static_cast(iModuleType)); if (it != g_mapModuleList.end()) { // 获取模块类型的字符串 std::string moduleTypeStr = it->second; // 通过调用 ModuleMoveTo 函数,传递不同的轴类型和位置 m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "X", pos.x); m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "Y", pos.y); m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "Z", pos.z); m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "R", pos.r); } else { // 如果找不到对应的模块类型,抛出错误或处理异常 std::cerr << "Invalid module type!" << std::endl; } } // slot:处理某行模板的前移/后移 void TemplateProgramPage::onMoveTemplate(QWidget* pageWidget, bool moveLeft) { // 1) 找到 templateId if (!m_mapPrTemplateWidgetIndex.contains(pageWidget)) return; int tmplId = m_mapPrTemplateWidgetIndex.value(pageWidget); // 2) 在 curentPrStrategy.vecTemplateId 中定位 auto& vec = curentPrStrategy->vecTemplateId; int idx = -1; for (int i = 0; i < (int)vec.size(); ++i) { if (vec[i].iTemplateId == tmplId) { idx = i; break; } } if (idx < 0) return; // 3) 计算目标位置并交换 int target = moveLeft ? idx - 1 : idx + 1; if (target < 0 || target >= (int)vec.size()) return; // 到头就不动 std::swap(vec[idx], vec[target]); // 4) 同步到 m_vecPrStrategy(持久化内存里也要动) for (auto& strat : m_vecPrStrategy) { if (strat.iStrategyId == curentPrStrategy->iStrategyId) { strat.vecTemplateId = curentPrStrategy->vecTemplateId; break; } } bool _falg = m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId); // 5) 重建当前 Tab 页的所有 templateWidget refreshCurrentTabLayout(); } // 根据 curentPrStrategy.vecTemplateId 顺序,重建 Tab 页里该策略下的所有 outWidget void TemplateProgramPage::refreshCurrentTabLayout() { if (curentPrStrategy == nullptr) { ui.tabWidget->setCurrentIndex(0); return; } // ui.tabWidget 是存策略 Tab 页的指针 int tabIndex = ui.tabWidget->currentIndex(); QWidget* page = ui.tabWidget->widget(tabIndex); if (!page) return; // 在 page 上布局了一列 outWidget auto* lay = qobject_cast(page->layout()); if (!lay) return; // 1) 取出所有现有 outWidget,先从布局里移除 QList olds; while (lay->count()) { auto* item = lay->takeAt(0); if (QWidget* w = item->widget()) { olds << w; // 不 delete,因为以后还要复用 w->setParent(nullptr); } delete item; } // 2) 按照 curentPrStrategy.vecTemplateId 新顺序,把对应 outWidget 重新加回去 for (auto& mt : curentPrStrategy->vecTemplateId) { int id = mt.iTemplateId; if (m_mapIndexPrTemplateWidget.contains(id)) { QWidget* w = m_mapIndexPrTemplateWidget.value(id); lay->addWidget(w); // 保证它还能响应事件 w->installEventFilter(this); } } // 3) 最后加一个伸缩项,保证顶部对齐 lay->addStretch(1); } // Event filter to handle the click event for images bool TemplateProgramPage::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::Enter) { for (int i = 0; i < m_imageLabels.size(); ++i) { if (object == m_imageLabels[i]) { showLargeImage(m_imagePixmaps[i], i); return true; } } } else if (event->type() == QEvent::Leave) { closeLargeImage(); return true; } else if (event->type() == QEvent::MouseButtonPress) { QWidget* clickedWidget = qobject_cast(object); if (clickedWidget && m_mapPrStrategyWidgetIndex.contains(clickedWidget)) { // 获取对应的策略 ID int strategyId = m_mapPrStrategyWidgetIndex.value(clickedWidget); for (auto& strategy : m_vecPrStrategy) { if (strategy.iStrategyId == strategyId) { curentPrStrategy = &strategy; break; } } // 获取当前策略的标签页名称 QString tabName = QString(tr("Stra %1","PR策略 %1")).arg(strategyId); // 检查 QTabWidget 中是否已存在该标签页 int existingTabIndex = -1; for (int i = 0; i < ui.tabWidget->count(); ++i) { if (ui.tabWidget->tabText(i) == tabName) { existingTabIndex = i; break; } } if (existingTabIndex != -1) { // 标签页已存在,直接切换到该标签页 ui.tabWidget->setCurrentIndex(existingTabIndex); } else { // 创建一个新的标签页 QWidget* newTab = new QWidget(); QVBoxLayout* tabLayout = new QVBoxLayout(newTab); // 根据模板 ID 顺序显示控件 auto& vecTemplateId = curentPrStrategy->vecTemplateId; for (size_t i = 0; i < vecTemplateId.size(); ++i) { int templateId = vecTemplateId[i].iTemplateId; // 根据 TemplateId 查找对应的 QWidget if (m_mapIndexPrTemplateWidget.contains(templateId)) { QWidget* templateWidget = m_mapIndexPrTemplateWidget.value(templateId); // 将模板控件添加到新的标签页 tabLayout->addWidget(templateWidget); } } newTab->setLayout(tabLayout); // 将新标签页添加到 QTabWidget 中 int tabIndex = ui.tabWidget->addTab(newTab, tabName); // 切换到新标签页 ui.tabWidget->setCurrentIndex(tabIndex); } // 设置选中效果 setSelectedStyle(clickedWidget); updateComboBox(strategyId); // 调用槽函数处理点击 return true; // 表示事件已处理 } } return QWidget::eventFilter(object, event); } // 设置选中样式的方法 void TemplateProgramPage::setSelectedStyle(QWidget* selectedWidget) { // 如果已经选中了其他组件,先清除选中样式 if (m_currentSelectedWidget && m_currentSelectedWidget != selectedWidget) { m_currentSelectedWidget->setStyleSheet(""); // 恢复默认样式 } // 设置当前选中组件的样式 selectedWidget->setStyleSheet("background-color: #D3D3D3;"); // 选中效果 //selectedWidget->setStyleSheet("background-color: #FFFFFF;"); // 默认背景颜色 // 更新当前选中的组件 m_currentSelectedWidget = selectedWidget; } void TemplateProgramPage::showLargeImage(const QPixmap& pixmap, int index) { // 如果已经存在,就不重复创建 if (!largeImageDialog) { largeImageDialog = new QDialog(this, Qt::Tool | Qt::FramelessWindowHint); largeImageDialog->setAttribute(Qt::WA_TranslucentBackground); largeImageLabel = new QLabel(largeImageDialog); largeImageLabel->setAlignment(Qt::AlignCenter); layout = new QVBoxLayout(); layout->addWidget(largeImageLabel); largeImageDialog->setLayout(layout); } largeImageLabel->setPixmap(pixmap); largeImageDialog->adjustSize(); // 将对话框放到鼠标左上方显示 QPoint globalPos = QCursor::pos(); largeImageDialog->move(globalPos + QPoint(-pixmap.width() - 20, -pixmap.height() - 20)); largeImageDialog->show(); } void TemplateProgramPage::closeLargeImage() { if (largeImageDialog) { largeImageDialog->hide(); } } /* * 缓存同步 */ LONG TemplateProgramPage::DeletePrTemplate(UINT iTemplateId) { // 在向量中查找匹配的模板 ID for (size_t i = 0; i < m_vecPrTemplate.size(); ++i) { if (m_vecPrTemplate[i].iTemplateId == iTemplateId) { // 删除该元素 m_vecPrTemplate.erase(m_vecPrTemplate.begin() + i); // 重新打编号 iNo_: 连续从 1 开始 for (size_t j = 0; j < m_vecPrTemplate.size(); ++j) { m_vecPrTemplate[j].iNo_ = static_cast(j) + 1; } return OK; } } // 如果没找到,返回错误码 return FAIL; } LONG TemplateProgramPage::DeleteStrategy(UINT iStrategyId) { // 在向量中查找匹配的策略 ID for (size_t i = 0; i < m_vecPrStrategy.size(); ++i) { if (m_vecPrStrategy[i].iStrategyId == iStrategyId) { // 删除该元素 m_vecPrStrategy.erase(m_vecPrStrategy.begin() + i); // 重新打编号 iNo_: 连续从 1 开始 for (size_t j = 0; j < m_vecPrStrategy.size(); ++j) { m_vecPrStrategy[j].iNo_ = static_cast(j) + 1; } return OK; } } // 如果没找到,返回错误码 return FAIL; }