TemplateProgramPage.cpp 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525
  1. #include "TemplateProgramPage.h"
  2. #include <QtWidgets/qinputdialog.h>
  3. #include <QtWidgets/qlistwidget.h>
  4. #include "Src/Common/JSignalSlotManager.h"
  5. std::unordered_map<int, bool> TemplateProgramPage::m_IdIsUsedMap;
  6. TemplateProgramPage::TemplateProgramPage(QWidget* parent)
  7. : QWidget(parent)
  8. {
  9. ui.setupUi(this);
  10. setStyleSheet(
  11. "QWidget { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F1F4FD, stop: 1 #E5E4F6); }"
  12. "QDoubleSpinBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }"
  13. "QSpinBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }"
  14. "QLineEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }"
  15. "QCheckBox::indicator { width: 20px; height: 20px; }"
  16. "QCheckBox::indicator:unchecked { background-color: #FFFFFF; border-radius: 2px; }"
  17. "QComboBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }"
  18. "QComboBox::drop-down { width: 20px; }"
  19. "QPushButton { background: #D0D0E8; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; }" // Button background color
  20. "QPushButton:hover { background-color: #B0B0D8; }" // Lighter color on hover
  21. "QPushButton:pressed { background-color: #A0A0C8; }" // Darker color on press
  22. );
  23. ui.comboBoxCurStraTemp->hide();
  24. ui.pushButtonSaveTemp->hide();
  25. ui.comboBoxCurStrategy->setEnabled(false);
  26. //QTabWidget* m_tabWidget = new QTabWidget(this); // 这里创建 QTabWidget
  27. //ui.verticalLayoutTemplate->addWidget(m_tabWidget); // 将 QStackedWidget 添加到布局中
  28. // 隐藏整个标签栏(包括标签名称)
  29. ui.tabWidget->tabBar()->hide();
  30. ui.pushButton1->hide();
  31. ui.pushButton2->hide();
  32. ui.pushButton3->hide();
  33. ui.pushButton4->hide();
  34. ui.pushButtonDelete->setIcon(QIcon(":/images/Program/deleteOuter.png"));
  35. ui.pushButtonAddStrategy->setIcon(QIcon(":/images/Program/addMatrix.png"));
  36. ui.pushButtonAddTemplate->setIcon(QIcon(":/images/Program/addMatrix.png"));
  37. m_manageDB = CManageDB::GetInstance();
  38. if (m_manageDB == nullptr) return;
  39. m_pProduct = m_manageDB->GetCProduct();
  40. if (m_pProduct == nullptr) return;
  41. m_pTemplateCViewInterface = ns_module::CViewInterface::GetInstance();
  42. m_CamerAndLamp = ns_module::CCamerAndLamp::GetInstance();
  43. initPage();
  44. }
  45. void TemplateProgramPage::initPage()
  46. {
  47. m_vecPrStrategy = m_manageDB->GetCProduct()->GetPrStrategy();
  48. m_vecPrTemplate = m_manageDB->GetCProduct()->GetPrTemplate();
  49. // Create Add PrStrategyPage
  50. for (int j = 0; j < m_vecPrStrategy.size(); j++)
  51. {
  52. AddPrStrategyPage(j, m_vecPrStrategy[j]);
  53. }
  54. // Create PrStrategyPage
  55. for (int j = 0; j < m_vecPrTemplate.size(); j++)
  56. {
  57. AddPrTemplatePage(j, m_vecPrTemplate[j]);
  58. }
  59. connect(ui.pushButtonSetPrStrategyRef, &QPushButton::clicked, this, [this]() {
  60. if (!curentPrStrategy) {
  61. JMessageTip::Message_warning(tr("Error !", "错误!"), tr("No strategy selected!", "没有选择策略!"), this);
  62. return;
  63. }
  64. // 设置 SetPrStrategyRef
  65. m_CamerAndLamp->SetPrStrategyRef(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId);
  66. curentPrStrategy = m_pProduct->GetPrStrategy(curentPrStrategy->iStrategyId);
  67. UpdatePrStrategyUI();
  68. // 添加提示信息
  69. JMessageTip::Message_information(tr("Success!","成功 !"), tr("Strategy reference has been set successfully."), this);
  70. });
  71. // Add策略
  72. connect(ui.pushButtonAddStrategy, &QPushButton::clicked, this, &TemplateProgramPage::onAddStrategyClicked);
  73. // Delete策略
  74. connect(ui.pushButtonDelete, &QPushButton::clicked, this, &TemplateProgramPage::onDeleteStrategyClicked);
  75. // Add模板
  76. connect(ui.pushButtonAddTemplate, &QPushButton::clicked, this, &TemplateProgramPage::onAddTemplateClicked);
  77. }
  78. void TemplateProgramPage::onAddStrategyClicked() {
  79. // 模拟 MODULE_LIST 列表中的各个项
  80. QStringList moduleNames = {
  81. tr("WafflePack", "华夫盒"),
  82. tr("WaffleHead", "华夫盒取晶头"),
  83. tr("WaffleTransferTable", "华夫盒中转台"),
  84. tr("WaferTable", "晶片台"),
  85. tr("Ejector", "顶针"),
  86. tr("WaferHead", "晶片取晶头"),
  87. tr("WaferTransferTable", "晶片台中转台"),
  88. tr("BondTable", "绑头"),
  89. tr("EutecticTable", "共晶台"),
  90. tr("DispenseHead", "点胶头"),
  91. tr("BondHead", "固晶头"),
  92. tr("SoliderTable", "流道"),
  93. tr("Load1", "上料"),
  94. tr("Unload1", "下料"),
  95. tr("NozzleTable", "吸嘴架"),
  96. tr("MaterialBox1", "料盒")
  97. };
  98. // 创建一个对话框显示模块选择列表
  99. QDialog dialog(this);
  100. dialog.setWindowTitle(tr("Choose Module", "选择模块"));
  101. QVBoxLayout* layout = new QVBoxLayout(&dialog);
  102. QListWidget* listWidget = new QListWidget(&dialog);
  103. // 填充模块选项
  104. for (int i = 0; i < moduleNames.size(); ++i) {
  105. QListWidgetItem* item = new QListWidgetItem(moduleNames[i]);
  106. item->setData(Qt::UserRole, i); // 把枚举的索引(模块ID)存储在 UserRole 中
  107. listWidget->addItem(item);
  108. }
  109. layout->addWidget(listWidget);
  110. // 创建水平布局,用于存放确认和取消按钮
  111. QHBoxLayout* buttonLayout = new QHBoxLayout();
  112. QPushButton* confirmButton = new QPushButton(tr("Confirm", "确定"), &dialog);
  113. buttonLayout->addWidget(confirmButton);
  114. QPushButton* cancelButton = new QPushButton(tr("Cancel", "取消"), &dialog);
  115. buttonLayout->addWidget(cancelButton);
  116. layout->addLayout(buttonLayout);
  117. // 禁用对话框的关闭按钮,强制用户选择
  118. dialog.setWindowFlag(Qt::WindowCloseButtonHint, false);
  119. // 确认按钮点击事件
  120. connect(confirmButton, &QPushButton::clicked, &dialog, &QDialog::accept);
  121. // 取消按钮点击事件
  122. connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject);
  123. // 显示对话框
  124. if (dialog.exec() == QDialog::Accepted) {
  125. QList<QListWidgetItem*> selectedItems = listWidget->selectedItems();
  126. if (selectedItems.isEmpty()) {
  127. JMessageTip::Message_warning(tr("Error !", "错误!"), tr("Please select a module!", "请选择一个模组!"), this);
  128. return;
  129. }
  130. // 通过 UserRole 获取选择的模块 ID
  131. int selectedModuleIndex = selectedItems.first()->data(Qt::UserRole).toInt();
  132. // 根据选中的模块索引创建策略
  133. MODULE_LIST moduleType = static_cast<MODULE_LIST>(selectedModuleIndex);
  134. UINT newStrategyId = 0;
  135. LONG ret = m_CamerAndLamp->CreatePrStrategy(moduleType, newStrategyId);
  136. if (ret == S_OK) {
  137. // 如果策略创建成功,获取新策略对象
  138. PR_STRATEGY* newPrStrategy = m_manageDB->GetCProduct()->GetPrStrategy(newStrategyId);
  139. if (newPrStrategy) {
  140. // 将新策略添加到 m_vecPrStrategy 中
  141. m_vecPrStrategy.push_back(*newPrStrategy);
  142. int vectorIndex = int(m_vecPrStrategy.size()) - 1;
  143. AddPrStrategyPage(vectorIndex, m_vecPrStrategy[vectorIndex]);
  144. // 如果需要进一步操作,比如更新 UI 或者做其他任务
  145. //JMessageTip::Message_information(tr("Success!", "成功 !"), tr("Strategy created and added successfully!"), this);
  146. m_StrategyOrTemplateChanged = true;
  147. //QTSignalSlotManager::get_instance()->SendSignalUpdateBondMatrixTemplateID(1, newStrategyId);
  148. }
  149. else {
  150. JMessageTip::Message_warning(tr("Error!","错误"), tr("Failed to retrieve strategy after creation","创建后检索策略失败"));
  151. }
  152. }
  153. else {
  154. JMessageTip::Message_warning(tr("Error!","错误"), tr("Failed to create strategyn","创建策略失败"));
  155. }
  156. }
  157. else {
  158. JMessageTip::Message_information(tr("Operation Canceled!","操作已取消!"), tr("The operation was canceled","操作已取消"), this);
  159. }
  160. }
  161. void TemplateProgramPage::onDeleteStrategyClicked() {
  162. // Step 1: Check if the strategy is selected
  163. if (!curentPrStrategy) {
  164. JMessageTip::Message_warning(tr("Error !", "错误!"), tr("No strategy selected!", "没有选择策略!"), this);
  165. return;
  166. }
  167. // Step 2: Confirm deletion of strategy
  168. QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Delete Strategy","删除策略"),
  169. tr("Are you sure you want to delete this strategy and its associated templates?","您确定要删除此策略及其关联的模板吗?"),
  170. QMessageBox::Yes | QMessageBox::No);
  171. if (reply == QMessageBox::No) {
  172. return; // User canceled the deletion
  173. }
  174. // Step 3: Iterate through the templates associated with the current strategy and delete them
  175. for (const auto& templateStruct : curentPrStrategy->vecTemplateId) {
  176. int templateId = templateStruct.iTemplateId;
  177. QWidget* templateWidget = m_mapIndexPrTemplateWidget.value(templateId, nullptr);
  178. if (templateWidget) {
  179. // Remove the template from the map
  180. m_mapPrTemplateWidgetIndex.remove(templateWidget);
  181. m_mapIndexPrTemplateWidget.remove(templateId);
  182. // Delete the template widget from the UI
  183. delete templateWidget; // This will delete the widget and remove it from the layout
  184. // Delete the template from the database
  185. m_manageDB->GetCProduct()->DeletePrTemplate(templateId);
  186. // Update local cache and remove template from the strategy's list
  187. DeletePrTemplate(templateId);
  188. // Remove the template from the strategy's template list
  189. auto it = std::remove_if(curentPrStrategy->vecTemplateId.begin(), curentPrStrategy->vecTemplateId.end(),
  190. [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; });
  191. curentPrStrategy->vecTemplateId.erase(it, curentPrStrategy->vecTemplateId.end());
  192. }
  193. }
  194. // Step 4: Delete the strategy itself
  195. int strategyId = curentPrStrategy->iStrategyId;
  196. // Remove the strategy from the map
  197. QWidget* strategyWidget = m_mapIndexPrStrategyWidget.value(strategyId, nullptr);
  198. if (strategyWidget) {
  199. m_mapPrStrategyWidgetIndex.remove(strategyWidget);
  200. m_mapIndexPrStrategyWidget.remove(strategyId);
  201. // Delete the strategy widget from the UI
  202. delete strategyWidget;
  203. }
  204. // Step 5: Remove the strategy from the database and local data structure
  205. m_manageDB->GetCProduct()->DeleteStrategy(strategyId);
  206. DeleteStrategy(strategyId);
  207. // Step 6: Remove the associated tab page for the strategy from the QTabWidget
  208. for (int i = 0; i < ui.tabWidget->count(); ++i) {
  209. if (ui.tabWidget->tabText(i) == QString(tr("Stra %1","PR策略 %1")).arg(strategyId)) {
  210. ui.tabWidget->removeTab(i); // Remove the tab associated with the strategy
  211. break;
  212. }
  213. }
  214. // Step 7: Clear the current strategy
  215. curentPrStrategy = nullptr;
  216. m_currentSelectedWidget = nullptr;
  217. // Step 8: Refresh the UI to reflect the changes
  218. refreshCurrentTabLayout();
  219. // Step 9: Show success message
  220. //JMessageTip::Message_information(tr("Success!"), tr("Strategy and associated templates deleted successfully!"), this);
  221. }
  222. void TemplateProgramPage::onAddTemplateClicked() {
  223. // 1) 取当前选中的策略索引
  224. int stratIndex = ui.tabWidget->currentIndex();
  225. if (!curentPrStrategy) {
  226. JMessageTip::Message_warning(tr("Error !", "错误!"), tr("No strategy selected!", "没有选择策略!"),this);
  227. return;
  228. }
  229. vector<CameraInfo> _cameraIdList = m_CamerAndLamp->GetCameraIdList(MODULE_LIST(curentPrStrategy->iModuleType));
  230. // 2) 如果相机列表只有一个,直接创建模板,否则弹出相机选择对话框
  231. if (_cameraIdList.size() == 1) {
  232. // 直接使用唯一相机
  233. CreateTemplate(_cameraIdList[0].iCameraId, stratIndex);
  234. }
  235. else {
  236. // 弹出相机选择对话框
  237. QDialog dialog(this);
  238. dialog.setWindowTitle(tr("Please Chose Camera", "请选择相机"));
  239. QVBoxLayout* layout = new QVBoxLayout(&dialog);
  240. QListWidget* listWidget = new QListWidget(&dialog);
  241. // 填充相机 ID 列表
  242. for (const CameraInfo& cam : _cameraIdList) {
  243. QListWidgetItem* item = new QListWidgetItem(QString::fromLocal8Bit(cam.name.c_str()));
  244. item->setData(Qt::UserRole, cam.iCameraId); // 把相机ID作为附加数据存进去
  245. listWidget->addItem(item);
  246. }
  247. layout->addWidget(listWidget);
  248. // 创建一个水平布局,用于存放按钮
  249. QHBoxLayout* buttonLayout = new QHBoxLayout();
  250. // 确认按钮
  251. QPushButton* confirmButton = new QPushButton(tr("Confirm", "确定"), &dialog);
  252. buttonLayout->addWidget(confirmButton);
  253. // 取消按钮
  254. QPushButton* cancelButton = new QPushButton(tr("Cancel", "取消"), &dialog);
  255. buttonLayout->addWidget(cancelButton);
  256. // 将水平布局添加到垂直布局中
  257. layout->addLayout(buttonLayout);
  258. // 禁用对话框的关闭按钮,强制用户选择
  259. dialog.setWindowFlag(Qt::WindowCloseButtonHint, false);
  260. // 确认按钮点击事件
  261. connect(confirmButton, &QPushButton::clicked, &dialog, &QDialog::accept);
  262. // 取消按钮点击事件
  263. connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject);
  264. // 显示对话框
  265. if (dialog.exec() == QDialog::Accepted) {
  266. QList<QListWidgetItem*> selectedItems = listWidget->selectedItems();
  267. if (selectedItems.isEmpty()) {
  268. JMessageTip::Message_warning(tr("Error !", "错误!"), tr("Please select a camera !","请选择一个相机 !"), this);
  269. return;
  270. }
  271. // 通过 UserRole 获取对应的相机 ID
  272. UINT _choseCameraId = selectedItems.first()->data(Qt::UserRole).toUInt();
  273. // 创建模板
  274. CreateTemplate(_choseCameraId, stratIndex);
  275. }
  276. else {
  277. // 用户点击取消按钮,关闭对话框并不执行任何操作
  278. JMessageTip::Message_information(("Operation Canceled !","操作已取消"), tr("The operation was canceled !","操作已取消!"), this);
  279. }
  280. }
  281. }
  282. // 封装模板创建的逻辑
  283. LONG TemplateProgramPage::CreateTemplate(UINT _choseCameraId, int stratIndex) {
  284. // 1) 调接口,创建新模板
  285. UINT newTplId = 0;
  286. LONG ret = m_CamerAndLamp->CreatePrTemplate(MODULE_LIST(curentPrStrategy->iModuleType), _choseCameraId, newTplId);
  287. if (ret != OK) {
  288. JMessageTip::Message_warning(tr("Error !", "错误!"), tr("Cannot create template !", "创建模板失败 !"), this);
  289. return FAIL;
  290. }
  291. // 2) 从数据库缓存中取回完整的 PR_TEMPLATE 对象
  292. PR_TEMPLATE* prTpl = m_pProduct->GetPrTemplate(newTplId);
  293. m_vecPrTemplate.push_back(*prTpl);
  294. int vectorIndex = int(m_vecPrTemplate.size()) - 1;
  295. // 3) 把它插入到策略的数据结构里
  296. MULTI_TEMP_STRUCT mts;
  297. mts.iTemplateId = newTplId;
  298. mts.eResultSelect = prTpl->eResultSelect;
  299. curentPrStrategy->vecTemplateId.push_back(mts);
  300. bool _falg = m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  301. //4) 调 AddPrTemplatePage 创建那个行 widget
  302. AddPrTemplatePage(vectorIndex, m_vecPrTemplate[vectorIndex]);
  303. //5) 既然这是当前页,就把它加到 Tab 的布局里
  304. QWidget* pageWidget = ui.tabWidget->widget(stratIndex);
  305. auto* vlay = qobject_cast<QVBoxLayout*>(pageWidget->layout());
  306. if (vlay) {
  307. // 插在最后一个 stretch 之前
  308. vlay->insertWidget(vlay->count(),
  309. m_mapIndexPrTemplateWidget.value(newTplId));
  310. }
  311. //6) 自动滚动到新添加的模板
  312. m_StrategyOrTemplateChanged = true;
  313. return OK;
  314. }
  315. void TemplateProgramPage::AddPrStrategyPage(int vectorIndex, _PR_STRATEGY prStrategy) {
  316. //所有的都显示
  317. QVector<QObject*> vecControls;
  318. QWidget* outWidget = new QWidget();
  319. QGridLayout* prStrategyGridLayout = new QGridLayout();
  320. prStrategyGridLayout->setSpacing(4);
  321. prStrategyGridLayout->setObjectName(QString::fromUtf8("prStrategy GridLayout"));
  322. prStrategyGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0
  323. QGridLayout* boxGridLayout = new QGridLayout();
  324. boxGridLayout->setSpacing(4);
  325. boxGridLayout->setObjectName(QString::fromUtf8("Box GridLayout"));
  326. boxGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0
  327. QHBoxLayout* buttonLayout = new QHBoxLayout();
  328. QSpacerItem* item = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  329. buttonLayout->addSpacerItem(item);
  330. QGroupBox* groupBox = new QGroupBox(outWidget);
  331. groupBox->setLayout(boxGridLayout);
  332. QGridLayout* matrixGridLayout = new QGridLayout();
  333. matrixGridLayout->setSpacing(4);
  334. matrixGridLayout->setObjectName(QString::fromUtf8("matrixGridLayout"));
  335. matrixGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0
  336. // Add matrix title
  337. QLabel* labelTitle = new QLabel(outWidget);
  338. labelTitle->setObjectName(QString::fromUtf8("labelTitle"));
  339. //labelTitle->setText(tr("PrStrategy: ") + QString::number(vectorIndex + 1));
  340. labelTitle->setText(tr("StrategyID:","PR策略ID:") + QString::number(prStrategy.iStrategyId));
  341. labelTitle->setStyleSheet("color: #6A78FF;height: 30px");
  342. matrixGridLayout->addWidget(labelTitle, 0, 0, 1, 1);
  343. vecControls.push_back(labelTitle);
  344. // Add Date
  345. QLabel* labelDate = new QLabel(outWidget);
  346. labelDate->setObjectName(QString::fromUtf8("labelDate"));
  347. labelDate->setText(tr("Date:","日期:") + QString::fromStdString(prStrategy.Date));
  348. matrixGridLayout->addWidget(labelDate, 0, 1, 1, 6);
  349. vecControls.push_back(labelDate);
  350. // Add Delete button
  351. //QPushButton* pushButtonDelete = new QPushButton(outWidget);
  352. //pushButtonDelete->setObjectName(QString::fromUtf8("button delete"));
  353. //pushButtonDelete->setText(tr("Dl"));
  354. //matrixGridLayout->addWidget(pushButtonDelete, 0, 8, 1, 1);
  355. //connect(pushButtonDelete, &QPushButton::clicked, this, [=]() {
  356. // //处理index
  357. // auto currentIt = m_mapPrStrategyWidgetIndex.find(outWidget);
  358. // int index = currentIt.value(); //迭代器 erase后currentIt被删除了
  359. // m_mapPrStrategyWidgetIndex.erase(currentIt);
  360. // delete outWidget;
  361. // });
  362. //// Add button 1
  363. //QPushButton* pushButton1 = new QPushButton(outWidget);
  364. //pushButton1->setObjectName(QString::fromUtf8("button 1"));
  365. //pushButton1->setText(tr("b1"));
  366. //matrixGridLayout->addWidget(pushButton1, 0, 2, 1, 1);
  367. //// Add button 2
  368. //QPushButton* pushButton2 = new QPushButton(outWidget);
  369. //pushButton2->setObjectName(QString::fromUtf8("button 2"));
  370. //pushButton2->setText(tr("b2"));
  371. //matrixGridLayout->addWidget(pushButton2, 0, 3, 1, 1);
  372. //// Add button 3
  373. //QPushButton* pushButton3 = new QPushButton(outWidget);
  374. //pushButton3->setObjectName(QString::fromUtf8("button 3"));
  375. //pushButton3->setText(tr("b3"));
  376. //matrixGridLayout->addWidget(pushButton3, 0, 4, 1, 1);
  377. //// Add button 4
  378. //QPushButton* pushButton4 = new QPushButton(outWidget);
  379. //pushButton4->setObjectName(QString::fromUtf8("button 4"));
  380. //pushButton4->setText(tr("b4"));
  381. //matrixGridLayout->addWidget(pushButton4, 0, 5, 1, 1);
  382. //// Add button 5
  383. //QPushButton* pushButton5 = new QPushButton(outWidget);
  384. //pushButton5->setObjectName(QString::fromUtf8("button 5"));
  385. //pushButton5->setText(tr("b5"));
  386. //matrixGridLayout->addWidget(pushButton5, 0, 6, 1, 1);
  387. //// Add button 6
  388. //QPushButton* pushButton6 = new QPushButton(outWidget);
  389. //pushButton6->setObjectName(QString::fromUtf8("button 6"));
  390. //pushButton6->setText(tr("b6"));
  391. //matrixGridLayout->addWidget(pushButton6, 0, 7, 1, 1);
  392. //// Add button 7
  393. //QPushButton* pushButton7 = new QPushButton(outWidget);
  394. //pushButton7->setObjectName(QString::fromUtf8("button 7"));
  395. //pushButton7->setText(tr("b7"));
  396. //matrixGridLayout->addWidget(pushButton7, 0, 8, 1, 1);
  397. //// Add ID
  398. //QLabel* labelPrStrategyID = new QLabel(outWidget);
  399. //labelPrStrategyID->setObjectName(QString::fromUtf8("labelPrStrategyID"));
  400. //labelPrStrategyID->setText(tr("PrStrategyID"));
  401. //matrixGridLayout->addWidget(labelPrStrategyID, 1, 0, 1, 1);
  402. //vecControls.push_back(labelPrStrategyID);
  403. //SpinBox* spinBoxPrStrategyID = new SpinBox(outWidget);
  404. //spinBoxPrStrategyID->setObjectName(QString::fromUtf8("spinBoxPrStrategyID"));
  405. //spinBoxPrStrategyID->setFixedWidth(95); // Set fixed width to 95
  406. //matrixGridLayout->addWidget(spinBoxPrStrategyID, 1, 1, 1, 1);
  407. //vecControls.push_back(spinBoxPrStrategyID);
  408. //XYR
  409. ////替换 DoubleSpinBox 为 QLabel
  410. //QLabel* labelPrStrategyXY = new QLabel(outWidget);
  411. //labelPrStrategyXY->setObjectName(QString::fromUtf8("labelPrStrategyXY"));
  412. //labelPrStrategyXY->setText(tr("ReferPos ")); // 参考点
  413. //matrixGridLayout->addWidget(labelPrStrategyXY, 2, 0, 1, 1);
  414. //vecControls.push_back(labelPrStrategyXY);
  415. //// RefX
  416. //QLabel* labelRefX = new QLabel(outWidget);
  417. //labelRefX->setObjectName(QString::fromUtf8("labelRefX"));
  418. //labelRefX->setText(tr("X:")); // 显示 prStrategy.stRef.x
  419. //matrixGridLayout->addWidget(labelRefX, 2, 1, 1, 1);
  420. //vecControls.push_back(labelRefX);
  421. ////QLabel* labelRefXData = new QLabel(outWidget);
  422. ////labelRefXData->setObjectName(QString::fromUtf8("labelRefXData"));
  423. ////labelRefXData->setText(QString::number(prStrategy.stRef.x)); // 显示 prStrategy.stRef.x
  424. ////matrixGridLayout->addWidget(labelRefXData, 2, 2, 1, 3);
  425. ////vecControls.push_back(labelRefXData);
  426. //// RefY
  427. //QLabel* labelRefY = new QLabel(outWidget);
  428. //labelRefY->setObjectName(QString::fromUtf8("labelRefY"));
  429. //labelRefY->setText(tr("Y:")); // 显示 prStrategy.stRef.y
  430. //matrixGridLayout->addWidget(labelRefY, 2, 5, 1, 1);
  431. //vecControls.push_back(labelRefY);
  432. ////QLabel* labelRefYData = new QLabel(outWidget);
  433. ////labelRefYData->setObjectName(QString::fromUtf8("labelRefYData"));
  434. ////labelRefYData->setText(tr("Y: ") + QString::number(prStrategy.stRef.y)); // 显示 prStrategy.stRef.y
  435. ////matrixGridLayout->addWidget(labelRefYData, 2, 6, 1, 3);
  436. ////vecControls.push_back(labelRefYData);
  437. //// Angle
  438. //QLabel* labelRefAngle = new QLabel(outWidget);
  439. //labelRefAngle->setObjectName(QString::fromUtf8("labelRefAngle"));
  440. //labelRefAngle->setText(tr("Angle:"));
  441. //matrixGridLayout->addWidget(labelRefAngle, 2, 9, 1, 2);
  442. //vecControls.push_back(labelRefAngle);
  443. //QLabel* labelRefAngleData = new QLabel(outWidget);
  444. //labelRefAngleData->setObjectName(QString::fromUtf8("labelRefAngleData"));
  445. //labelRefAngleData->setText(tr("Angle: ") + QString::number(prStrategy.stRef.a));
  446. //matrixGridLayout->addWidget(labelRefAngleData, 2, 9, 2, 2);
  447. //vecControls.push_back(labelRefAngleData);*/
  448. //DoubleSpinBox* doubleSpinBoxRefX = new DoubleSpinBox(outWidget);
  449. //doubleSpinBoxRefX->setObjectName(QString::fromUtf8("doubleSpinBoxRefX"));
  450. ////doubleSpinBoxRefX->setFixedWidth(106); // Set fixed width to 95
  451. //matrixGridLayout->addWidget(doubleSpinBoxRefX, 2, 2, 1, 3);
  452. //vecControls.push_back(doubleSpinBoxRefX);
  453. //DoubleSpinBox* doubleSpinBoxRefY = new DoubleSpinBox(outWidget);
  454. //doubleSpinBoxRefY->setObjectName(QString::fromUtf8("doubleSpinBoxRefY"));
  455. ////doubleSpinBoxRefY->setFixedWidth(106); // Set fixed width to 95
  456. //matrixGridLayout->addWidget(doubleSpinBoxRefY, 2, 6, 1, 3);
  457. //vecControls.push_back(doubleSpinBoxRefY);
  458. //DoubleSpinBox* doubleSpinBoxRefA = new DoubleSpinBox(outWidget);
  459. //doubleSpinBoxRefA->setObjectName(QString::fromUtf8("doubleSpinBoxRefA"));
  460. ////doubleSpinBoxRefA->setFixedWidth(106); // Set fixed width to 95
  461. //matrixGridLayout->addWidget(doubleSpinBoxRefA, 2, 9, 1, 2);
  462. //vecControls.push_back(doubleSpinBoxRefA);
  463. //QLabel* labelPrStrategyAngle = new QLabel(outWidget);
  464. //labelPrStrategyAngle->setObjectName(QString::fromUtf8("labelPrStrategyAngle"));
  465. //labelPrStrategyAngle->setText(tr("Angle"));
  466. //matrixGridLayout->addWidget(labelPrStrategyAngle, 3, 0, 1, 1);
  467. //vecControls.push_back(labelPrStrategyAngle);
  468. //// 替换 DoubleSpinBox 为 QLabel 显示 RefA
  469. //QLabel* labelRefA = new QLabel(outWidget);
  470. //labelRefA->setObjectName(QString::fromUtf8("labelRefA"));
  471. //labelRefA->setText(QString::number(prStrategy.stRef.a)); // 显示 prStrategy.stRef.a
  472. //matrixGridLayout->addWidget(labelRefA, 3, 1, 1, 4);
  473. //vecControls.push_back(labelRefA);
  474. QLabel* labelPrStrategyXY = new QLabel(outWidget);
  475. labelPrStrategyXY->setObjectName(QString::fromUtf8("labelPrStrategyXY"));
  476. labelPrStrategyXY->setText(tr("RefPos X&Y","参考位置:X&Y"));//参考点
  477. matrixGridLayout->addWidget(labelPrStrategyXY, 2, 0, 1, 1);
  478. vecControls.push_back(labelPrStrategyXY);
  479. DoubleSpinBox* doubleSpinBoxRefX = new DoubleSpinBox(outWidget);
  480. doubleSpinBoxRefX->setObjectName(QString::fromUtf8("doubleSpinBoxRefX"));
  481. doubleSpinBoxRefX->setFixedWidth(130); // Set fixed width to 95
  482. matrixGridLayout->addWidget(doubleSpinBoxRefX, 2, 1, 1, 4);
  483. vecControls.push_back(doubleSpinBoxRefX);
  484. DoubleSpinBox* doubleSpinBoxRefY = new DoubleSpinBox(outWidget);
  485. doubleSpinBoxRefY->setObjectName(QString::fromUtf8("doubleSpinBoxRefY"));
  486. doubleSpinBoxRefY->setFixedWidth(130); // Set fixed width to 95
  487. matrixGridLayout->addWidget(doubleSpinBoxRefY, 2, 5, 1, 4);
  488. vecControls.push_back(doubleSpinBoxRefY);
  489. QLabel* labelPrStrategyAngle = new QLabel(outWidget);
  490. labelPrStrategyAngle->setObjectName(QString::fromUtf8("labelPrStrategyAngle"));
  491. labelPrStrategyAngle->setText(tr("Refpos Angle","参考角度"));
  492. matrixGridLayout->addWidget(labelPrStrategyAngle, 3, 0, 1, 1);
  493. vecControls.push_back(labelPrStrategyAngle);
  494. DoubleSpinBox* doubleSpinBoxRefA = new DoubleSpinBox(outWidget);
  495. doubleSpinBoxRefA->setObjectName(QString::fromUtf8("doubleSpinBoxRefA"));
  496. doubleSpinBoxRefA->setFixedWidth(130); // Set fixed width to 95
  497. matrixGridLayout->addWidget(doubleSpinBoxRefA, 3, 1, 1, 4);
  498. vecControls.push_back(doubleSpinBoxRefA);
  499. doubleSpinBoxRefX->setValue(prStrategy.stRef.x);
  500. doubleSpinBoxRefX->setReadOnly(true); // 设置为只读,用户不能修改
  501. doubleSpinBoxRefY->setValue(prStrategy.stRef.y);
  502. doubleSpinBoxRefY->setReadOnly(true); // 设置为只读,用户不能修改
  503. doubleSpinBoxRefA->setValue(prStrategy.stRef.a);
  504. doubleSpinBoxRefA->setReadOnly(true); // 设置为只读,用户不能修改
  505. //SpinBox* spinBoxDate = new SpinBox(outWidget);
  506. //spinBoxDate->setObjectName(QString::fromUtf8("spinBoxDate"));
  507. //spinBoxDate->setFixedWidth(95); // Set fixed width to 95
  508. //matrixGridLayout->addWidget(spinBoxDate, 2, 2, 1, 1);
  509. //vecControls.push_back(spinBoxDate);
  510. QFrame* line = new QFrame(outWidget);
  511. line->setFrameShape(QFrame::NoFrame); // 移除默认框架
  512. line->setFixedHeight(2); // 设置固定高度
  513. line->setStyleSheet("background-color: #C7CAEB;");
  514. boxGridLayout->addLayout(matrixGridLayout, 2, 0);
  515. boxGridLayout->addWidget(line);
  516. //prStrategyGridLayout->addLayout(buttonLayout, 1, 0);
  517. prStrategyGridLayout->addWidget(groupBox);
  518. outWidget->setLayout(prStrategyGridLayout);
  519. outWidget->setStyleSheet("");
  520. ui.verticalLayoutStrategy->addWidget(outWidget);
  521. ui.verticalLayoutStrategy->setContentsMargins(0, 0, 0, 0); // Adjust margins if necessary
  522. ui.verticalLayoutStrategy->setAlignment(Qt::AlignTop | Qt::AlignLeft); // Align the layout to the top-left
  523. m_mapPrStrategyWidgetIndex.insert(outWidget, prStrategy.iStrategyId);
  524. m_mapIndexPrStrategyWidget.insert(prStrategy.iStrategyId, outWidget);
  525. // 点击时的操作
  526. outWidget->installEventFilter(this);
  527. //connect(spinBoxRow, &SpinBox::editDone, this, [=]() {
  528. // m_vectBondMatrixs[vectorIndex].BondMatrixRow = spinBoxRow->value();
  529. // });
  530. //connect(spinBoxCol, &SpinBox::editDone, this, [=]() {
  531. // m_vectBondMatrixs[vectorIndex].BondMatrixCol = spinBoxCol->value();
  532. // });
  533. //connect(doubleSpinBoxLeftTopX, &DoubleSpinBox::editDone, this, [=]() {
  534. // m_vectBondMatrixs[vectorIndex].LeftTopPoint.x = doubleSpinBoxLeftTopX->value();
  535. // });
  536. //connect(doubleSpinBoxLeftTopY, &DoubleSpinBox::editDone, this, [=]() {
  537. // m_vectBondMatrixs[vectorIndex].LeftTopPoint.y = doubleSpinBoxLeftTopY->value();
  538. // });
  539. //connect(doubleSpinBoxRightTopX, &DoubleSpinBox::editDone, this, [=]() {
  540. // m_vectBondMatrixs[vectorIndex].RightTopPoint.x = doubleSpinBoxRightTopX->value();
  541. // });
  542. //connect(doubleSpinBoxRightTopY, &DoubleSpinBox::editDone, this, [=]() {
  543. // m_vectBondMatrixs[vectorIndex].RightTopPoint.y = doubleSpinBoxRightTopY->value();
  544. // });
  545. //connect(doubleSpinBoxRightButtomX, &DoubleSpinBox::editDone, this, [=]() {
  546. // m_vectBondMatrixs[vectorIndex].RightBottomPoint.x = doubleSpinBoxRightButtomX->value();
  547. // });
  548. //connect(doubleSpinBoxRightButtomY, &DoubleSpinBox::editDone, this, [=]() {
  549. // m_vectBondMatrixs[vectorIndex].RightBottomPoint.y = doubleSpinBoxRightButtomY->value();
  550. // });
  551. //connect(lineEditNoBondPts, &QLineEdit::textChanged, this, [=]() {
  552. // });
  553. }
  554. void TemplateProgramPage::UpdatePrStrategyUI() {
  555. if (!curentPrStrategy) {
  556. return; // 如果没有当前策略,不做更新
  557. }
  558. // 获取当前策略ID
  559. int strategyId = curentPrStrategy->iStrategyId;
  560. // 更新策略ID显示
  561. if (m_mapIndexPrStrategyWidget.contains(strategyId)) {
  562. QWidget* outWidget = m_mapIndexPrStrategyWidget.value(strategyId);
  563. // 更新策略ID标签
  564. QLabel* labelTitle = outWidget->findChild<QLabel*>("labelTitle");
  565. if (labelTitle) {
  566. labelTitle->setText(tr("StrategyID: ","策略id:") + QString::number(curentPrStrategy->iStrategyId));
  567. }
  568. // 更新日期标签
  569. QLabel* labelDate = outWidget->findChild<QLabel*>("labelDate");
  570. if (labelDate) {
  571. labelDate->setText(tr("Date: ","日起:") + QString::fromStdString(curentPrStrategy->Date));
  572. }
  573. // 更新参考点位置X和Y
  574. DoubleSpinBox* doubleSpinBoxRefX = outWidget->findChild<DoubleSpinBox*>("doubleSpinBoxRefX");
  575. if (doubleSpinBoxRefX) {
  576. doubleSpinBoxRefX->setValue(curentPrStrategy->stRef.x);
  577. doubleSpinBoxRefX->setReadOnly(true); // 设置为只读
  578. }
  579. DoubleSpinBox* doubleSpinBoxRefY = outWidget->findChild<DoubleSpinBox*>("doubleSpinBoxRefY");
  580. if (doubleSpinBoxRefY) {
  581. doubleSpinBoxRefY->setValue(curentPrStrategy->stRef.y);
  582. doubleSpinBoxRefY->setReadOnly(true); // 设置为只读
  583. }
  584. DoubleSpinBox* doubleSpinBoxRefA = outWidget->findChild<DoubleSpinBox*>("doubleSpinBoxRefA");
  585. if (doubleSpinBoxRefA) {
  586. doubleSpinBoxRefA->setValue(curentPrStrategy->stRef.a);
  587. doubleSpinBoxRefA->setReadOnly(true); // 设置为只读
  588. }
  589. }
  590. }
  591. void TemplateProgramPage::updateComboBox(UINT currentStrategyId) {
  592. // 清空下拉框
  593. ui.comboBoxCurStrategy->clear();
  594. // 填充所有策略的ID
  595. for (const auto& strategy : m_vecPrStrategy) {
  596. ui.comboBoxCurStrategy->addItem(QString::number(strategy.iStrategyId));
  597. }
  598. // 将当前策略ID设置为选中项
  599. ui.comboBoxCurStrategy->setCurrentText(QString::number(currentStrategyId));
  600. }
  601. void TemplateProgramPage::AddPrTemplatePage(int vectorIndex, PR_TEMPLATE& prTemplate) {
  602. //全部添加进去后,只显示当前PrStrategy的PrTemplate
  603. QVector<QObject*> vecControls;
  604. QWidget* outWidget = new QWidget();
  605. QGridLayout* prStrategyGridLayout = new QGridLayout();
  606. prStrategyGridLayout->setSpacing(2);
  607. prStrategyGridLayout->setObjectName(QString::fromUtf8("prStrategy GridLayout"));
  608. prStrategyGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0
  609. QGridLayout* boxGridLayout = new QGridLayout();
  610. boxGridLayout->setSpacing(2);
  611. boxGridLayout->setObjectName(QString::fromUtf8("Box GridLayout"));
  612. boxGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0
  613. QHBoxLayout* buttonLayout = new QHBoxLayout();
  614. QSpacerItem* item = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  615. buttonLayout->addSpacerItem(item);
  616. QGroupBox* groupBox = new QGroupBox(outWidget);
  617. groupBox->setLayout(boxGridLayout);
  618. QGridLayout* matrixGridLayout = new QGridLayout();
  619. matrixGridLayout->setSpacing(2);
  620. matrixGridLayout->setObjectName(QString::fromUtf8("matrixGridLayout"));
  621. matrixGridLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距为0
  622. // Add matrix title
  623. QLabel* labelTitle = new QLabel(outWidget);
  624. labelTitle->setObjectName(QString::fromUtf8("labelTitle"));
  625. //labelTitle->setText(tr("PrStrategy: ") + QString::number(vectorIndex + 1));
  626. labelTitle->setText(tr("TempID: ", "模板ID: ") + QString::number(prTemplate.iTemplateId));
  627. labelTitle->setStyleSheet("color: #6A78FF;height: 30px");
  628. matrixGridLayout->addWidget(labelTitle, 0, 0, 1, 1);
  629. vecControls.push_back(labelTitle);
  630. // Add Date
  631. QLabel* labelDate = new QLabel(outWidget);
  632. labelDate->setObjectName(QString::fromUtf8("labelDate"));
  633. labelDate->setText(tr("Date: ", "日期: ")+ QString::fromStdString(prTemplate.Date));
  634. matrixGridLayout->addWidget(labelDate, 0, 1, 1, 6);
  635. vecControls.push_back(labelDate);
  636. //QLineEdit* lineEditDate = new QLineEdit(outWidget);
  637. //lineEditDate->setObjectName(QString::fromUtf8("lineEditDate"));
  638. //matrixGridLayout->addWidget(lineEditDate, 0, 1, 1, 6);
  639. //vecControls.push_back(lineEditDate);
  640. //lineEditDate->setReadOnly(true);
  641. //lineEditDate->setCursor(Qt::PointingHandCursor);
  642. //lineEditDate->setProperty("vectorIndex", vectorIndex); // 存储索引
  643. //lineEditDate->setProperty("parentMatrixIndex", -1); // 设置父矩阵的索引
  644. //lineEditDate->installEventFilter(this);
  645. // Add Delete Out Matrix button
  646. QPushButton* pushButtonDelete = new QPushButton(outWidget);
  647. pushButtonDelete->setObjectName(QString::fromUtf8("button delete"));
  648. pushButtonDelete->setToolTip(tr("DeleteTemplate", "删除模板")); // 设置鼠标悬停时显示的文字提示
  649. pushButtonDelete->setIcon(QIcon(":/images/Program/deleteInner.png"));
  650. //pushButtonDelete->setText(tr("Dl"));
  651. matrixGridLayout->addWidget(pushButtonDelete, 0, 7, 1, 1);
  652. connect(pushButtonDelete, &QPushButton::clicked, this, [=]() {
  653. //处理index
  654. //auto currentIt = m_mapPrTemplateWidgetIndex.find(outWidget);
  655. //int index = currentIt.value(); //迭代器 erase后currentIt被删除了
  656. ////删除Map
  657. //m_mapPrTemplateWidgetIndex.erase(currentIt);
  658. // 1) 先拿到这个 widget 对应的 templateId
  659. if (!m_mapPrTemplateWidgetIndex.contains(outWidget))
  660. return; // 防御,万一映射里没它
  661. int templateId = m_mapPrTemplateWidgetIndex.value(outWidget);
  662. // 2) 从两张表里都移除
  663. m_mapPrTemplateWidgetIndex.remove(outWidget);
  664. m_mapIndexPrTemplateWidget.remove(templateId);
  665. //调接口删除数据
  666. m_manageDB->GetCProduct()->DeletePrTemplate(templateId);
  667. //更新本地缓存
  668. DeletePrTemplate(templateId);
  669. //m_vecPrStrategy = m_manageDB->GetCProduct()->GetPrStrategy();
  670. for (auto it = curentPrStrategy->vecTemplateId.begin(); it != curentPrStrategy->vecTemplateId.end(); ++it) {
  671. if (it->iTemplateId == templateId) {
  672. curentPrStrategy->vecTemplateId.erase(it);
  673. break; // 删除完一个后退出循环
  674. }
  675. }
  676. //更新DB缓存
  677. m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  678. //删除布局
  679. delete outWidget;
  680. m_StrategyOrTemplateChanged = true;
  681. });
  682. //// Add button 1
  683. //QPushButton* pushButton1 = new QPushButton(outWidget);
  684. //pushButton1->setObjectName(QString::fromUtf8("button 1"));
  685. //pushButton1->setText(tr("b1"));
  686. //matrixGridLayout->addWidget(pushButton1, 0, 6, 1, 1);
  687. // button 2
  688. QPushButton* buttonMoveForward = new QPushButton(outWidget);
  689. buttonMoveForward->setObjectName(QString::fromUtf8("buttonMoveForward"));
  690. buttonMoveForward->setText(QString::fromLocal8Bit("↑"));//⇑
  691. buttonMoveForward->setToolTip(tr("MoveForward", "前移")); // 设置鼠标悬停时显示的文字提示
  692. matrixGridLayout->addWidget(buttonMoveForward, 1, 7, 1, 1);
  693. // button 3
  694. QPushButton* buttonMoveBack = new QPushButton(outWidget);
  695. buttonMoveBack->setObjectName(QString::fromUtf8("buttonMoveBack"));
  696. buttonMoveBack->setText(QString::fromLocal8Bit("↓"));//⇓
  697. buttonMoveBack->setToolTip(tr("MoveBack", "后移")); // 设置鼠标悬停时显示的文字提示
  698. matrixGridLayout->addWidget(buttonMoveBack, 2, 7, 1, 1);
  699. // button 4
  700. QPushButton* buttonEdit = new QPushButton(outWidget);
  701. buttonEdit->setObjectName(QString::fromUtf8("buttonEdit"));
  702. buttonEdit->setToolTip(tr("EditTemplate", "编辑模板")); // 设置鼠标悬停时显示的文字提示
  703. //buttonEdit->setText(tr("Ed"));
  704. buttonEdit->setIcon(QIcon(":/images/Program/editTemplate.png"));
  705. matrixGridLayout->addWidget(buttonEdit, 3, 7, 1, 1);
  706. // button MoveTo
  707. QPushButton* pushButtonMoveToXYZR = new QPushButton(outWidget);
  708. pushButtonMoveToXYZR->setObjectName(QString::fromUtf8("pushButtonMoveToXYZR"));
  709. pushButtonMoveToXYZR->setToolTip(tr("MoveToGrabPos", "移动到拍照位置")); // 设置鼠标悬停时显示的文字提示
  710. pushButtonMoveToXYZR->setIcon(QIcon(":/images/Program/moveTo.png"));
  711. matrixGridLayout->addWidget(pushButtonMoveToXYZR, 4, 7, 1, 1);
  712. connect(pushButtonMoveToXYZR, &QPushButton::clicked, this, [=]() {
  713. bool reply = JMessageTip::Message_question(tr("Confirmation", "确认操作"), tr("Are all the axes confirmed to have moved to the template position ?", "确定所有轴移动到模板位置?"), this);
  714. if (reply)
  715. TemplateMoveToXYZRAxisPosition(prTemplate.iModuleType, prTemplate.stGrabPos);
  716. });
  717. //灯光
  718. QPushButton* pushButtonAllLight = new QPushButton(outWidget);
  719. pushButtonAllLight->setObjectName(QString::fromUtf8("pushButtonAllLight"));
  720. pushButtonAllLight->setToolTip(tr("SetAllLight", "设置所有灯光")); // 设置鼠标悬停时显示的文字提示
  721. pushButtonAllLight->setText(QString::fromLocal8Bit("L"));
  722. matrixGridLayout->addWidget(pushButtonAllLight, 0, 8, 1, 1);
  723. connect(pushButtonAllLight, &QPushButton::clicked, this, [=]() {
  724. //QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Confirmation", "确认操作"), tr("Are you sure you want to change the lighting settings?", "是否确定修改灯光设置?"), QMessageBox::Yes | QMessageBox::No);
  725. //if (reply == QMessageBox::Yes)
  726. {
  727. m_CamerAndLamp->SetRedLight(prTemplate.iCameraId, prTemplate.iRedLight);
  728. m_CamerAndLamp->SetBlueLight(prTemplate.iCameraId, prTemplate.iBlueLight);
  729. m_CamerAndLamp->SetGreenLight(prTemplate.iCameraId, prTemplate.iBlueLight);
  730. m_CamerAndLamp->SetPointLight(prTemplate.iCameraId, prTemplate.iPointLight);
  731. }
  732. });
  733. // button TakePhoto
  734. QPushButton* pushButtonTakePhoto = new QPushButton(outWidget);
  735. pushButtonTakePhoto->setObjectName(QString::fromUtf8("pushButtonTakePhoto"));
  736. pushButtonTakePhoto->setText(QString::fromLocal8Bit("TP"));
  737. pushButtonTakePhoto->setToolTip(tr("TakePhoto", "拍照")); // 设置鼠标悬停时显示的文字提示
  738. matrixGridLayout->addWidget(pushButtonTakePhoto, 1, 8, 1, 1);
  739. // button 4
  740. QPushButton* pushButtonBlueLight = new QPushButton(outWidget);
  741. pushButtonBlueLight->setObjectName(QString::fromUtf8("pushButtonBlueLight"));
  742. pushButtonBlueLight->setText(tr("bt1"));
  743. matrixGridLayout->addWidget(pushButtonBlueLight, 2, 8, 1, 1);
  744. // button 5
  745. QPushButton* pushButtonPointLight = new QPushButton(outWidget);
  746. pushButtonPointLight->setObjectName(QString::fromUtf8("pushButtonPointLight"));
  747. pushButtonPointLight->setText(tr("bt2"));
  748. matrixGridLayout->addWidget(pushButtonPointLight, 3, 8, 1, 1);
  749. // button 5
  750. QPushButton* pushButton5 = new QPushButton(outWidget);
  751. pushButton5->setObjectName(QString::fromUtf8("button 5"));
  752. pushButton5->setText(tr("b5"));
  753. matrixGridLayout->addWidget(pushButton5, 4, 8, 1, 1);
  754. connect(buttonMoveForward, &QPushButton::clicked, this, [this, outWidget]() {
  755. onMoveTemplate(outWidget, /*MoveForward=*/true);
  756. });
  757. connect(buttonMoveBack, &QPushButton::clicked, this, [this, outWidget]() {
  758. onMoveTemplate(outWidget, /*MoveForward=*/false);
  759. });
  760. connect(buttonEdit, &QPushButton::clicked, this, [=]() {
  761. // 调用 ModifyBondMatrixTemplate 函数
  762. if (m_pTemplateCViewInterface) {
  763. m_pTemplateCViewInterface->GetViewMatrix()->ModifyBondMatrixTemplate(prTemplate.iTemplateId);
  764. }
  765. });
  766. // CameraID
  767. QLabel* labelCameraID = new QLabel(outWidget);
  768. labelCameraID->setObjectName(QString::fromUtf8("labelCameraID"));
  769. labelCameraID->setText(tr("CameraID", "相机ID: "));
  770. matrixGridLayout->addWidget(labelCameraID, 1, 0, 1, 1);
  771. vecControls.push_back(labelCameraID);
  772. SpinBox* spinBoxCameraID = new SpinBox(outWidget);
  773. spinBoxCameraID->setObjectName(QString::fromUtf8("spinBoxDate"));
  774. //spinBoxCameraID->setFixedWidth(50); // Set fixed width to 95
  775. matrixGridLayout->addWidget(spinBoxCameraID, 1, 1, 1, 2);
  776. vecControls.push_back(spinBoxCameraID);
  777. // TempResult
  778. QLabel* labelTempResult = new QLabel(outWidget);
  779. labelTempResult->setObjectName(QString::fromUtf8("labelTempResult"));
  780. labelTempResult->setText(tr("TempResult", "模板结果ID: "));
  781. matrixGridLayout->addWidget(labelTempResult, 2, 0, 2, 1);
  782. vecControls.push_back(labelTempResult);
  783. // 1. X
  784. QCheckBox* checkX = new QCheckBox(outWidget);
  785. checkX->setObjectName(QString::fromUtf8("checkX"));
  786. checkX->setText(tr("X"));
  787. matrixGridLayout->addWidget(checkX, 2, 1, 1, 1);
  788. vecControls.push_back(checkX);
  789. // 2. AngleX
  790. QCheckBox* checkAngleX = new QCheckBox(outWidget);
  791. checkAngleX->setObjectName(QString::fromUtf8("checkAngleX"));
  792. checkAngleX->setText(tr("AngleX", "X角度"));
  793. matrixGridLayout->addWidget(checkAngleX, 2, 2, 1, 1);
  794. vecControls.push_back(checkAngleX);
  795. // 3. Y
  796. QCheckBox* checkY = new QCheckBox(outWidget);
  797. checkY->setObjectName(QString::fromUtf8("checkY"));
  798. checkY->setText(tr("Y"));
  799. matrixGridLayout->addWidget(checkY, 3, 1, 1, 1);
  800. vecControls.push_back(checkY);
  801. // 4. AngleY
  802. QCheckBox* checkAngleY = new QCheckBox(outWidget);
  803. checkAngleY->setObjectName(QString::fromUtf8("checkAngleY"));
  804. checkAngleY->setText(tr("AngleY", "Y角度"));
  805. matrixGridLayout->addWidget(checkAngleY, 3, 2, 1, 1);
  806. vecControls.push_back(checkAngleY);
  807. prTemplate.eResultSelect;
  808. // 根据 prTemplate.eResultSelect 初始化状态
  809. checkX->setChecked(prTemplate.eResultSelect & OUT_X);
  810. checkY->setChecked(prTemplate.eResultSelect & OUT_Y);
  811. checkAngleX->setChecked(prTemplate.eResultSelect & OUT_Ax);
  812. checkAngleY->setChecked(prTemplate.eResultSelect & OUT_Ay);
  813. //auto bindResultSelectToggle = [this, outWidget](QCheckBox* check,
  814. // SEARCH_OUT bitMaskToSet,
  815. // SEARCH_OUT bitMaskToClear = static_cast<SEARCH_OUT>(0))
  816. //{
  817. // connect(check, &QCheckBox::toggled, this, [this, outWidget, bitMaskToSet, bitMaskToClear](bool checked) {
  818. // // 1) 取出模板 ID
  819. // int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1);
  820. // if (templateId < 0) return;
  821. // // 2) 在 vector 里找到对应条目
  822. // auto it = std::find_if(m_vecPrTemplate.begin(),
  823. // m_vecPrTemplate.end(),
  824. // [templateId](auto& pr) { return pr.iTemplateId == templateId; });
  825. // if (it == m_vecPrTemplate.end()) return;
  826. // // 3) 更新 eResultSelect
  827. // int flags = int(it->eResultSelect);
  828. // if (checked) {
  829. // flags |= int(bitMaskToSet);
  830. // if (bitMaskToClear != 0) flags &= ~int(bitMaskToClear);
  831. // }
  832. // else {
  833. // flags &= ~int(bitMaskToSet);
  834. // }
  835. // it->eResultSelect = static_cast<SEARCH_OUT>(flags);
  836. // });
  837. //};
  838. //// 然后把四个 connect 全部改成调用它:
  839. //bindResultSelectToggle(checkX, OUT_X);
  840. //bindResultSelectToggle(checkY, OUT_Y);
  841. //bindResultSelectToggle(checkAngleX, OUT_Ax, OUT_Ay);
  842. //bindResultSelectToggle(checkAngleY, OUT_Ay, OUT_Ax);
  843. // --- X 改变只负责更新 OUT_X 位 ---
  844. connect(checkX, &QCheckBox::toggled, this, [=](bool checked) {
  845. int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1);
  846. if (templateId < 0) return;
  847. auto it = std::find_if(m_vecPrTemplate.begin(),
  848. m_vecPrTemplate.end(),
  849. [templateId](auto& pr) { return pr.iTemplateId == templateId; });
  850. if (it == m_vecPrTemplate.end()) return;
  851. auto m = static_cast<int>(it->eResultSelect);
  852. if (checked) m |= OUT_X; else m &= ~OUT_X;
  853. it->eResultSelect = static_cast<SEARCH_OUT>(m);
  854. // 更新 vecTemplateId 中对应的模板
  855. auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(),
  856. curentPrStrategy->vecTemplateId.end(),
  857. [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; });
  858. // 如果找到对应模板,更新它的 eResultSelect
  859. if (vecIt != curentPrStrategy->vecTemplateId.end()) {
  860. vecIt->eResultSelect = it->eResultSelect;
  861. }
  862. m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  863. m_vecPrTemplate[vectorIndex].eResultSelect;
  864. });
  865. // --- Y 改变只负责更新 OUT_Y 位 ---
  866. connect(checkY, &QCheckBox::toggled, this, [=](bool checked) {
  867. int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1);
  868. if (templateId < 0) return;
  869. auto it = std::find_if(m_vecPrTemplate.begin(),
  870. m_vecPrTemplate.end(),
  871. [templateId](auto& pr) { return pr.iTemplateId == templateId; });
  872. if (it == m_vecPrTemplate.end()) return;
  873. auto m = static_cast<int>(it->eResultSelect);
  874. if (checked) m |= OUT_Y; else m &= ~OUT_Y;
  875. it->eResultSelect = static_cast<SEARCH_OUT>(m);
  876. // 更新 vecTemplateId 中对应的模板
  877. auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(),
  878. curentPrStrategy->vecTemplateId.end(),
  879. [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; });
  880. // 如果找到对应模板,更新它的 eResultSelect
  881. if (vecIt != curentPrStrategy->vecTemplateId.end()) {
  882. vecIt->eResultSelect = it->eResultSelect;
  883. }
  884. m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  885. m_vecPrTemplate[vectorIndex].eResultSelect;
  886. });
  887. // --- AngleX 勾上时取消 AngleY 并更新 OUT_Ax ---
  888. connect(checkAngleX, &QCheckBox::toggled, this, [=](bool checked) {
  889. int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1);
  890. if (templateId < 0) return;
  891. auto it = std::find_if(m_vecPrTemplate.begin(),
  892. m_vecPrTemplate.end(),
  893. [templateId](auto& pr) { return pr.iTemplateId == templateId; });
  894. if (it == m_vecPrTemplate.end()) return;
  895. int m = int(it->eResultSelect);
  896. if (checked) {
  897. QSignalBlocker b(checkAngleY);
  898. checkAngleY->setChecked(false);
  899. m &= ~OUT_Ay; // ← 清除 Ay 位
  900. m |= OUT_Ax; // 设置 Ax 位
  901. }
  902. else {
  903. m &= ~OUT_Ax; // 取消 Ax 位
  904. }
  905. it->eResultSelect = static_cast<SEARCH_OUT>(m);
  906. // 更新 vecTemplateId 中对应的模板
  907. auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(),
  908. curentPrStrategy->vecTemplateId.end(),
  909. [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; });
  910. // 如果找到对应模板,更新它的 eResultSelect
  911. if (vecIt != curentPrStrategy->vecTemplateId.end()) {
  912. vecIt->eResultSelect = it->eResultSelect;
  913. }
  914. m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  915. m_vecPrTemplate[vectorIndex].eResultSelect;
  916. });
  917. // --- AngleY 勾上时取消 AngleX 并更新 OUT_Ay ---
  918. connect(checkAngleY, &QCheckBox::toggled, this, [=](bool checked) {
  919. int templateId = m_mapPrTemplateWidgetIndex.value(outWidget, -1);
  920. if (templateId < 0) return;
  921. auto it = std::find_if(m_vecPrTemplate.begin(),
  922. m_vecPrTemplate.end(),
  923. [templateId](auto& pr) { return pr.iTemplateId == templateId; });
  924. if (it == m_vecPrTemplate.end()) return;
  925. int m = int(it->eResultSelect);
  926. if (checked) {
  927. QSignalBlocker b(checkAngleX);
  928. checkAngleX->setChecked(false);
  929. m &= ~OUT_Ax; // ← 清除 Ax 位
  930. m |= OUT_Ay; // 设置 Ay 位
  931. }
  932. else {
  933. m &= ~OUT_Ay; // 取消 Ay 位
  934. }
  935. it->eResultSelect = static_cast<SEARCH_OUT>(m);
  936. // 更新 vecTemplateId 中对应的模板
  937. auto vecIt = std::find_if(curentPrStrategy->vecTemplateId.begin(),
  938. curentPrStrategy->vecTemplateId.end(),
  939. [templateId](const MULTI_TEMP_STRUCT& mts) { return mts.iTemplateId == templateId; });
  940. // 如果找到对应模板,更新它的 eResultSelect
  941. if (vecIt != curentPrStrategy->vecTemplateId.end()) {
  942. vecIt->eResultSelect = it->eResultSelect;
  943. }
  944. m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  945. m_vecPrTemplate[vectorIndex].eResultSelect;
  946. });
  947. //
  948. QLabel* labelPrMethod = new QLabel(outWidget);
  949. labelPrMethod->setObjectName(QString::fromUtf8("labelPrMethod"));
  950. labelPrMethod->setText(tr("PrMethod"));
  951. matrixGridLayout->addWidget(labelPrMethod, 4, 0, 1, 1);
  952. vecControls.push_back(labelPrMethod);
  953. SpinBox* spinBoxPrMethod = new SpinBox(outWidget);
  954. spinBoxPrMethod->setObjectName(QString::fromUtf8("spinBoxPrMethod"));
  955. //spinBoxPrMethod->setFixedWidth(50); // Set fixed width to 95
  956. matrixGridLayout->addWidget(spinBoxPrMethod, 4, 1, 1, 2);
  957. vecControls.push_back(spinBoxPrMethod);
  958. JVision::ImageInfo imageInfo;
  959. if (m_CamerAndLamp->GetTemplateImage(prTemplate.iTemplateId, imageInfo) == OK)
  960. {
  961. // 1) 根据 ImageFormat 决定 QImage::Format
  962. QImage::Format qtFmt;
  963. int bytesPerLine = 0;
  964. switch (imageInfo.format)
  965. {
  966. case JVision::ImageFormat::GRAY8:
  967. qtFmt = QImage::Format_Grayscale8;
  968. bytesPerLine = imageInfo.width * 1;
  969. break;
  970. case JVision::ImageFormat::RGB888:
  971. qtFmt = QImage::Format_RGB888;
  972. bytesPerLine = imageInfo.width * 3;
  973. break;
  974. case JVision::ImageFormat::ARGB32:
  975. qtFmt = QImage::Format_ARGB32;
  976. bytesPerLine = imageInfo.width * 4;
  977. break;
  978. case JVision::ImageFormat::RGB32:
  979. // QImage::Format_RGB32 存储格式也是 0xffRRGGBB
  980. qtFmt = QImage::Format_RGB32;
  981. bytesPerLine = imageInfo.width * 4;
  982. break;
  983. case JVision::ImageFormat::YUV422:
  984. // 如果要支持 YUV422,这里需要先把 imageInfo.data 转成 RGB 或 ARGB
  985. // 比如用 OpenCV cv::cvtColor,或者自己写转换。
  986. throw std::runtime_error("YUV422 尚未实现转换");
  987. break;
  988. default:
  989. throw std::runtime_error("不支持的图像格式");
  990. }
  991. // 2) 用原始内存构造 QImage — 注意这不会复制数据,所以后面要 copy() 一下或保证 data 的生命周期足够
  992. QImage img(imageInfo.data,
  993. imageInfo.width,
  994. imageInfo.height,
  995. bytesPerLine,
  996. qtFmt);
  997. // 3) 如果 data 是 BGR 排序(而非 RGB),可以:
  998. // img = img.rgbSwapped();
  999. // 4) 将 QImage 转为 QPixmap
  1000. QPixmap pixmap = QPixmap::fromImage(img.copy()); // copy() 让 QPixmap 拷贝一份,后面可以安全 delete[] data
  1001. // 5) 显示到 QLabel(跟原来的一样)
  1002. QLabel* imageLabel = new QLabel(outWidget);
  1003. imageLabel->setPixmap(pixmap.scaled(110, 110,
  1004. Qt::KeepAspectRatio,
  1005. Qt::SmoothTransformation));
  1006. imageLabel->setAlignment(Qt::AlignCenter);
  1007. imageLabel->setFixedSize(110, 110);
  1008. matrixGridLayout->addWidget(imageLabel, 1, 3, 4, 4);
  1009. vecControls.push_back(imageLabel);
  1010. imageLabel->installEventFilter(this); // Install event filter to catch click events on the label
  1011. m_imageLabels.push_back(imageLabel);
  1012. m_imagePixmaps.push_back(pixmap);
  1013. // 6) 释放 ImageInfo 分配的内存
  1014. //delete[] imageInfo.data;
  1015. }
  1016. else
  1017. {
  1018. // 拿图失败处理……
  1019. }
  1020. // Load the image
  1021. //QString imagePath = "D:/config/db/Product1/2/ShapeMode.shm.jpg";
  1022. //QPixmap pixmap(imagePath);
  1023. //// Create a QLabel to display the image in a smaller size
  1024. //QLabel* imageLabel = new QLabel(outWidget);
  1025. //imageLabel->setPixmap(pixmap.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); // Set size to 200x150, keeping aspect ratio
  1026. //imageLabel->setAlignment(Qt::AlignCenter); // Align the image in the center of the label
  1027. //imageLabel->setFixedSize(120, 120); // Set the maximum size for the image label
  1028. //// Add the image label to the grid layout
  1029. //matrixGridLayout->addWidget(imageLabel, 1, 3, 4, 4); // From row 1, column 2 to row 3, column 6
  1030. //vecControls.push_back(imageLabel);
  1031. //// Connect click event for the image label
  1032. //imageLabel->setCursor(Qt::PointingHandCursor); // Set cursor to hand to indicate clickability
  1033. //imageLabel->installEventFilter(this); // Install event filter to catch click events on the label
  1034. //// Store the QLabel and QPixmap for later use
  1035. //m_imageLabels.push_back(imageLabel);
  1036. //m_imagePixmaps.push_back(pixmap);
  1037. QFrame* line = new QFrame(outWidget);
  1038. line->setFrameShape(QFrame::NoFrame); // 移除默认框架
  1039. line->setFixedHeight(2); // 设置固定高度
  1040. line->setStyleSheet("background-color: #C7CAEB;");
  1041. boxGridLayout->addLayout(matrixGridLayout, 2, 0);
  1042. boxGridLayout->addWidget(line);
  1043. //prStrategyGridLayout->addLayout(buttonLayout, 1, 0);
  1044. prStrategyGridLayout->addWidget(groupBox);
  1045. outWidget->setLayout(prStrategyGridLayout);
  1046. //ui.verticalLayoutTemplate->addWidget(outWidget);
  1047. //ui.verticalLayoutTemplate->setContentsMargins(0, 0, 0, 0); // Adjust margins if necessary
  1048. //ui.verticalLayoutTemplate->setAlignment(Qt::AlignTop | Qt::AlignLeft); // Align the layout to the top-left
  1049. m_mapPrTemplateWidgetIndex.insert(outWidget, prTemplate.iTemplateId);
  1050. m_mapIndexPrTemplateWidget.insert(prTemplate.iTemplateId, outWidget);
  1051. spinBoxCameraID->setValue(prTemplate.iCameraId);
  1052. spinBoxCameraID->setReadOnly(true); // 设置为只读,用户不能修改
  1053. //spinBoxTempResult->setValue(prTemplate.eResultSelect);
  1054. //spinBoxTempResult->setReadOnly(true); // 设置为只读,用户不能修改
  1055. spinBoxPrMethod->setValue(prTemplate.iPrMethod);
  1056. spinBoxPrMethod->setReadOnly(true); // 设置为只读,用户不能修改
  1057. //lineEditDate->setText(QString::fromStdString(prTemplate.Date));
  1058. //lineEditDate->setReadOnly(true); // 设置为只读,用户不能修改
  1059. }
  1060. void TemplateProgramPage::TemplateMoveToXYZRAxisPosition(UINT iModuleType, X_Y_Z_R_STRUCT pos)
  1061. {
  1062. // 将 iModuleType 转换为对应的字符串
  1063. auto it = g_mapModuleList.find(static_cast<MODULE_LIST>(iModuleType));
  1064. if (it != g_mapModuleList.end()) {
  1065. // 获取模块类型的字符串
  1066. std::string moduleTypeStr = it->second;
  1067. // 通过调用 ModuleMoveTo 函数,传递不同的轴类型和位置
  1068. m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "X", pos.x);
  1069. m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "Y", pos.y);
  1070. m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "Z", pos.z);
  1071. m_pTemplateCViewInterface->GetViewMotion()->ModuleMoveTo(moduleTypeStr, "R", pos.r);
  1072. }
  1073. else {
  1074. // 如果找不到对应的模块类型,抛出错误或处理异常
  1075. std::cerr << "Invalid module type!" << std::endl;
  1076. }
  1077. }
  1078. // slot:处理某行模板的前移/后移
  1079. void TemplateProgramPage::onMoveTemplate(QWidget* pageWidget, bool moveLeft) {
  1080. // 1) 找到 templateId
  1081. if (!m_mapPrTemplateWidgetIndex.contains(pageWidget)) return;
  1082. int tmplId = m_mapPrTemplateWidgetIndex.value(pageWidget);
  1083. // 2) 在 curentPrStrategy.vecTemplateId 中定位
  1084. auto& vec = curentPrStrategy->vecTemplateId;
  1085. int idx = -1;
  1086. for (int i = 0; i < (int)vec.size(); ++i) {
  1087. if (vec[i].iTemplateId == tmplId) { idx = i; break; }
  1088. }
  1089. if (idx < 0) return;
  1090. // 3) 计算目标位置并交换
  1091. int target = moveLeft ? idx - 1 : idx + 1;
  1092. if (target < 0 || target >= (int)vec.size()) return; // 到头就不动
  1093. std::swap(vec[idx], vec[target]);
  1094. // 4) 同步到 m_vecPrStrategy(持久化内存里也要动)
  1095. for (auto& strat : m_vecPrStrategy) {
  1096. if (strat.iStrategyId == curentPrStrategy->iStrategyId) {
  1097. strat.vecTemplateId = curentPrStrategy->vecTemplateId;
  1098. break;
  1099. }
  1100. }
  1101. bool _falg = m_CamerAndLamp->SetPrStrategyTemplate(MODULE_LIST(curentPrStrategy->iModuleType), curentPrStrategy->iStrategyId, curentPrStrategy->vecTemplateId);
  1102. // 5) 重建当前 Tab 页的所有 templateWidget
  1103. refreshCurrentTabLayout();
  1104. }
  1105. // 根据 curentPrStrategy.vecTemplateId 顺序,重建 Tab 页里该策略下的所有 outWidget
  1106. void TemplateProgramPage::refreshCurrentTabLayout() {
  1107. if (curentPrStrategy == nullptr) {
  1108. ui.tabWidget->setCurrentIndex(0);
  1109. return;
  1110. }
  1111. // ui.tabWidget 是存策略 Tab 页的指针
  1112. int tabIndex = ui.tabWidget->currentIndex();
  1113. QWidget* page = ui.tabWidget->widget(tabIndex);
  1114. if (!page) return;
  1115. // 在 page 上布局了一列 outWidget
  1116. auto* lay = qobject_cast<QVBoxLayout*>(page->layout());
  1117. if (!lay) return;
  1118. // 1) 取出所有现有 outWidget,先从布局里移除
  1119. QList<QWidget*> olds;
  1120. while (lay->count()) {
  1121. auto* item = lay->takeAt(0);
  1122. if (QWidget* w = item->widget()) {
  1123. olds << w;
  1124. // 不 delete,因为以后还要复用
  1125. w->setParent(nullptr);
  1126. }
  1127. delete item;
  1128. }
  1129. // 2) 按照 curentPrStrategy.vecTemplateId 新顺序,把对应 outWidget 重新加回去
  1130. for (auto& mt : curentPrStrategy->vecTemplateId) {
  1131. int id = mt.iTemplateId;
  1132. if (m_mapIndexPrTemplateWidget.contains(id)) {
  1133. QWidget* w = m_mapIndexPrTemplateWidget.value(id);
  1134. lay->addWidget(w);
  1135. // 保证它还能响应事件
  1136. w->installEventFilter(this);
  1137. }
  1138. }
  1139. // 3) 最后加一个伸缩项,保证顶部对齐
  1140. lay->addStretch(1);
  1141. }
  1142. // Event filter to handle the click event for images
  1143. bool TemplateProgramPage::eventFilter(QObject* object, QEvent* event) {
  1144. if (event->type() == QEvent::Enter) {
  1145. for (int i = 0; i < m_imageLabels.size(); ++i) {
  1146. if (object == m_imageLabels[i]) {
  1147. showLargeImage(m_imagePixmaps[i], i);
  1148. return true;
  1149. }
  1150. }
  1151. }
  1152. else if (event->type() == QEvent::Leave) {
  1153. closeLargeImage();
  1154. return true;
  1155. }
  1156. else if (event->type() == QEvent::MouseButtonPress) {
  1157. QWidget* clickedWidget = qobject_cast<QWidget*>(object);
  1158. if (clickedWidget && m_mapPrStrategyWidgetIndex.contains(clickedWidget)) {
  1159. // 获取对应的策略 ID
  1160. int strategyId = m_mapPrStrategyWidgetIndex.value(clickedWidget);
  1161. for (auto& strategy : m_vecPrStrategy) {
  1162. if (strategy.iStrategyId == strategyId) {
  1163. curentPrStrategy = &strategy;
  1164. break;
  1165. }
  1166. }
  1167. // 获取当前策略的标签页名称
  1168. QString tabName = QString(tr("Stra %1","PR策略 %1")).arg(strategyId);
  1169. // 检查 QTabWidget 中是否已存在该标签页
  1170. int existingTabIndex = -1;
  1171. for (int i = 0; i < ui.tabWidget->count(); ++i) {
  1172. if (ui.tabWidget->tabText(i) == tabName) {
  1173. existingTabIndex = i;
  1174. break;
  1175. }
  1176. }
  1177. if (existingTabIndex != -1) {
  1178. // 标签页已存在,直接切换到该标签页
  1179. ui.tabWidget->setCurrentIndex(existingTabIndex);
  1180. }
  1181. else {
  1182. // 创建一个新的标签页
  1183. QWidget* newTab = new QWidget();
  1184. QVBoxLayout* tabLayout = new QVBoxLayout(newTab);
  1185. // 根据模板 ID 顺序显示控件
  1186. auto& vecTemplateId = curentPrStrategy->vecTemplateId;
  1187. for (size_t i = 0; i < vecTemplateId.size(); ++i) {
  1188. int templateId = vecTemplateId[i].iTemplateId;
  1189. // 根据 TemplateId 查找对应的 QWidget
  1190. if (m_mapIndexPrTemplateWidget.contains(templateId)) {
  1191. QWidget* templateWidget = m_mapIndexPrTemplateWidget.value(templateId);
  1192. // 将模板控件添加到新的标签页
  1193. tabLayout->addWidget(templateWidget);
  1194. }
  1195. }
  1196. newTab->setLayout(tabLayout);
  1197. // 将新标签页添加到 QTabWidget 中
  1198. int tabIndex = ui.tabWidget->addTab(newTab, tabName);
  1199. // 切换到新标签页
  1200. ui.tabWidget->setCurrentIndex(tabIndex);
  1201. }
  1202. // 设置选中效果
  1203. setSelectedStyle(clickedWidget);
  1204. updateComboBox(strategyId); // 调用槽函数处理点击
  1205. return true; // 表示事件已处理
  1206. }
  1207. }
  1208. return QWidget::eventFilter(object, event);
  1209. }
  1210. // 设置选中样式的方法
  1211. void TemplateProgramPage::setSelectedStyle(QWidget* selectedWidget) {
  1212. // 如果已经选中了其他组件,先清除选中样式
  1213. if (m_currentSelectedWidget && m_currentSelectedWidget != selectedWidget) {
  1214. m_currentSelectedWidget->setStyleSheet(""); // 恢复默认样式
  1215. }
  1216. // 设置当前选中组件的样式
  1217. selectedWidget->setStyleSheet("background-color: #D3D3D3;");
  1218. // 选中效果
  1219. //selectedWidget->setStyleSheet("background-color: #FFFFFF;"); // 默认背景颜色
  1220. // 更新当前选中的组件
  1221. m_currentSelectedWidget = selectedWidget;
  1222. }
  1223. void TemplateProgramPage::showLargeImage(const QPixmap& pixmap, int index)
  1224. {
  1225. // 如果已经存在,就不重复创建
  1226. if (!largeImageDialog) {
  1227. largeImageDialog = new QDialog(this, Qt::Tool | Qt::FramelessWindowHint);
  1228. largeImageDialog->setAttribute(Qt::WA_TranslucentBackground);
  1229. largeImageLabel = new QLabel(largeImageDialog);
  1230. largeImageLabel->setAlignment(Qt::AlignCenter);
  1231. layout = new QVBoxLayout();
  1232. layout->addWidget(largeImageLabel);
  1233. largeImageDialog->setLayout(layout);
  1234. }
  1235. largeImageLabel->setPixmap(pixmap);
  1236. largeImageDialog->adjustSize();
  1237. // 将对话框放到鼠标左上方显示
  1238. QPoint globalPos = QCursor::pos();
  1239. largeImageDialog->move(globalPos + QPoint(-pixmap.width() - 20, -pixmap.height() - 20));
  1240. largeImageDialog->show();
  1241. }
  1242. void TemplateProgramPage::closeLargeImage() {
  1243. if (largeImageDialog) {
  1244. largeImageDialog->hide();
  1245. }
  1246. }
  1247. /*
  1248. * 缓存同步
  1249. */
  1250. LONG TemplateProgramPage::DeletePrTemplate(UINT iTemplateId)
  1251. {
  1252. // 在向量中查找匹配的模板 ID
  1253. for (size_t i = 0; i < m_vecPrTemplate.size(); ++i)
  1254. {
  1255. if (m_vecPrTemplate[i].iTemplateId == iTemplateId)
  1256. {
  1257. // 删除该元素
  1258. m_vecPrTemplate.erase(m_vecPrTemplate.begin() + i);
  1259. // 重新打编号 iNo_: 连续从 1 开始
  1260. for (size_t j = 0; j < m_vecPrTemplate.size(); ++j)
  1261. {
  1262. m_vecPrTemplate[j].iNo_ = static_cast<int>(j) + 1;
  1263. }
  1264. return OK;
  1265. }
  1266. }
  1267. // 如果没找到,返回错误码
  1268. return FAIL;
  1269. }
  1270. LONG TemplateProgramPage::DeleteStrategy(UINT iStrategyId)
  1271. {
  1272. // 在向量中查找匹配的策略 ID
  1273. for (size_t i = 0; i < m_vecPrStrategy.size(); ++i)
  1274. {
  1275. if (m_vecPrStrategy[i].iStrategyId == iStrategyId)
  1276. {
  1277. // 删除该元素
  1278. m_vecPrStrategy.erase(m_vecPrStrategy.begin() + i);
  1279. // 重新打编号 iNo_: 连续从 1 开始
  1280. for (size_t j = 0; j < m_vecPrStrategy.size(); ++j)
  1281. {
  1282. m_vecPrStrategy[j].iNo_ = static_cast<int>(j) + 1;
  1283. }
  1284. return OK;
  1285. }
  1286. }
  1287. // 如果没找到,返回错误码
  1288. return FAIL;
  1289. }