WaferProgramPage.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. #include "WaferProgramPage.h"
  2. std::unordered_map<int, bool> WaferProgramPage::idIsUsedMap;
  3. WaferProgramPage::WaferProgramPage(QWidget* parent)
  4. : QWidget(parent)
  5. {
  6. QVBoxLayout* mainLayout = new QVBoxLayout(this);
  7. m_pCProduct = CManageDB::GetInstance()->GetCProduct();
  8. // 从数据库中加载数据
  9. m_pCProduct->LoadDataByDB();
  10. // 创建表格
  11. mergedTable = new QTableWidget(this);
  12. mergedTable->setColumnCount(11); // 11 列,包含 Matrix 和 DieMatrix 的所有字段
  13. mergedTable->setHorizontalHeaderLabels({
  14. "MatrixID", "MatrixRow", "MatrixCol", "LeftTopPoint_Y", "LeftTopPoint_X",
  15. "RightTopPoint_X", "RightTopPoint_Y", "RightBottomPoint_X", "RightBottomPoint_Y",
  16. "DieMatrixId", "NoBondPt"
  17. });
  18. mergedTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
  19. // 创建按钮布局
  20. QHBoxLayout* buttonLayout = new QHBoxLayout();
  21. QPushButton* addRowButton = new QPushButton("Add", this);
  22. QPushButton* deleteRowButton = new QPushButton("Delete", this);
  23. QPushButton* updateButton = new QPushButton("Update", this);
  24. buttonLayout->addWidget(addRowButton);
  25. buttonLayout->addWidget(deleteRowButton);
  26. buttonLayout->addWidget(updateButton);
  27. QString buttonStyle = R"(
  28. QPushButton {
  29. background-color: #f0f0f0;
  30. border: 1px solid #b0b0b0;
  31. border-radius: 4px;
  32. padding: 4px 12px;
  33. }
  34. QPushButton:hover {
  35. background-color: #e0e0ff;
  36. }
  37. QPushButton:pressed {
  38. background-color: #d0d0ff;
  39. }
  40. )";
  41. addRowButton->setStyleSheet(buttonStyle);
  42. deleteRowButton->setStyleSheet(buttonStyle);
  43. updateButton->setStyleSheet(buttonStyle);
  44. // 将控件添加到布局
  45. mainLayout->addWidget(mergedTable);
  46. mainLayout->addLayout(buttonLayout);
  47. setLayout(mainLayout);
  48. // 连接按钮和槽
  49. connect(addRowButton, &QPushButton::clicked, this, &WaferProgramPage::addRow);
  50. connect(deleteRowButton, &QPushButton::clicked, this, &WaferProgramPage::deleteRow);
  51. connect(updateButton, &QPushButton::clicked, this, &WaferProgramPage::updateData);
  52. connect(mergedTable, &QTableWidget::cellChanged, this, &WaferProgramPage::onCellChanged);
  53. connect(mergedTable, &QTableWidget::cellDoubleClicked, this, [=](int row, int column) {
  54. if (column == 9) {
  55. QComboBox* comboBox = createDieMatrixIdComboBox(m_VecWaferMatrix[row].iDieMatrixId, row);
  56. mergedTable->setCellWidget(row, column, comboBox);
  57. comboBox->showPopup(); // 可选:自动展开下拉
  58. // 记录初始值(以防没有变化)
  59. int originalValue = comboBox->currentData().toInt();
  60. // 1. 用户选择后立即还原
  61. connect(comboBox, QOverload<int>::of(&QComboBox::activated), this, [=](int index) {
  62. int selectedId = comboBox->itemData(index).toInt();
  63. m_VecWaferMatrix[row].iDieMatrixId = selectedId;
  64. mergedTable->removeCellWidget(row, column);
  65. mergedTable->setItem(row, column, new QTableWidgetItem(QString::number(selectedId)));
  66. });
  67. // 2. 用户没有选中,仅点击其他地方,触发还原
  68. connect(comboBox, &QComboBox::hidePopup, this, [=]() {
  69. // 如果还在表格里,就还原(防止重复)
  70. if (mergedTable->cellWidget(row, column) == comboBox) {
  71. int selectedId = comboBox->currentData().toInt();
  72. m_VecWaferMatrix[row].iDieMatrixId = selectedId;
  73. mergedTable->removeCellWidget(row, column);
  74. mergedTable->setItem(row, column, new QTableWidgetItem(QString::number(selectedId)));
  75. }
  76. });
  77. }
  78. });
  79. connect(mergedTable, &QTableWidget::cellDoubleClicked, this, [=](int row, int column) {
  80. if (column == 10) { // NoBondPt 列
  81. const auto& wafer = m_VecWaferMatrix[row];
  82. NoBondPtEditDialog dlg(wafer.MatrixRow, wafer.MatrixCol, wafer.VecNoBondPt, this);
  83. if (dlg.exec() == QDialog::Accepted) {
  84. // 获取用户选择结果
  85. QVector<XY_LONG_STRUCT> selected = dlg.getSelectedPoints();
  86. // 更新数据结构
  87. m_VecWaferMatrix[row].VecNoBondPt.clear();
  88. for (const auto& pt : selected) {
  89. m_VecWaferMatrix[row].VecNoBondPt.push_back(pt);
  90. }
  91. // 转换为字符串填入表格
  92. QStringList ptList;
  93. for (const auto& pt : selected) {
  94. ptList << QString("(%1,%2)").arg(pt.x).arg(pt.y);
  95. }
  96. mergedTable->setItem(row, column, new QTableWidgetItem(ptList.join(" ")));
  97. }
  98. }
  99. });
  100. // 初始化表格数据
  101. initMergedData();
  102. }
  103. //QWidget* WaferProgramPage::CreateWaferProgramPage(const CONFIG_BASE_STRUCT& control) {
  104. // return new WaferProgramPage();
  105. //}
  106. //创建下拉列表
  107. QComboBox* WaferProgramPage::createDieMatrixIdComboBox(int defaultId, int row) {
  108. QComboBox* comboBox = new QComboBox(mergedTable);
  109. // 设置样式,确保在暗色模式下也是白底黑字
  110. comboBox->setStyleSheet(R"(
  111. QComboBox {
  112. background-color: white;
  113. color: black;
  114. border: 1px solid #BABBDC;
  115. border-radius: 4px;
  116. padding: 2px 5px;
  117. }
  118. QComboBox QAbstractItemView {
  119. background-color: white;
  120. color: black;
  121. selection-background-color: #E5E5FF;
  122. selection-color: black;
  123. }
  124. )");
  125. for (const auto& dieMatrix : m_VecDieMatrixt) {
  126. /*comboBox->addItem(
  127. QString("%1 - %2").arg(dieMatrix.MatrixId).arg(QString::fromStdString(dieMatrix.strModuleName)),
  128. QVariant(dieMatrix.MatrixId)
  129. );*/
  130. comboBox->addItem(QString::number(dieMatrix.MatrixId), QVariant(dieMatrix.MatrixId));
  131. }
  132. int index = comboBox->findData(defaultId);
  133. if (index >= 0)
  134. comboBox->setCurrentIndex(index);
  135. return comboBox;
  136. }
  137. void WaferProgramPage::initMergedData() {
  138. m_isInitializing = true;
  139. SqlOperation& sqlOp = SqlOperation::GetInstance();
  140. QList<QJsonObject> directories;
  141. int userPrivilege = 0;//?
  142. sqlOp.GetDirectories("Dir_Programme", userPrivilege, directories); // 使用相应的表名和权限加载目录
  143. m_VecWaferMatrix = m_pCProduct->GetWaferMatrix();
  144. for (const PROGRAM_WAFER_MATRIX_STRUCT& wafer : m_VecWaferMatrix) {
  145. int row = mergedTable->rowCount();
  146. mergedTable->insertRow(row);
  147. PROGRAM_DIE_MATRIX_STRUCT stDieMatrix;
  148. m_pCProduct->GetDieMatrix(wafer.MatrixId, stDieMatrix);
  149. m_VecDieMatrixt.push_back(stDieMatrix);
  150. // 填充表格数据
  151. mergedTable->setItem(row, 0, new QTableWidgetItem(QString::number(wafer.MatrixId))); // MatrixID
  152. mergedTable->setItem(row, 1, new QTableWidgetItem(QString::number(wafer.MatrixRow))); // MatrixRow
  153. mergedTable->setItem(row, 2, new QTableWidgetItem(QString::number(wafer.MatrixCol))); // MatrixCol
  154. mergedTable->setItem(row, 3, new QTableWidgetItem(QString::number(wafer.LeftTopPoint.y))); // LeftTopPoint_Y
  155. mergedTable->setItem(row, 4, new QTableWidgetItem(QString::number(wafer.LeftTopPoint.x))); // LeftTopPoint_X
  156. mergedTable->setItem(row, 5, new QTableWidgetItem(QString::number(wafer.RightTopPoint.x))); // RightTopPoint_X
  157. mergedTable->setItem(row, 6, new QTableWidgetItem(QString::number(wafer.RightTopPoint.y))); // RightTopPoint_Y
  158. mergedTable->setItem(row, 7, new QTableWidgetItem(QString::number(wafer.RightBottomPoint.x))); // RightBottomPoint_X
  159. mergedTable->setItem(row, 8, new QTableWidgetItem(QString::number(wafer.RightBottomPoint.y))); // RightBottomPoint_Y
  160. mergedTable->setItem(row, 9, new QTableWidgetItem(QString::number(wafer.iDieMatrixId))); // DieMatrixId
  161. // 填充 NoBondPt 数据
  162. QStringList noBondPts;
  163. for (const XY_LONG_STRUCT& pt : wafer.VecNoBondPt) {
  164. noBondPts.append(QString("(%1,%2)").arg(pt.x).arg(pt.y));
  165. }
  166. mergedTable->setItem(row, 10, new QTableWidgetItem(noBondPts.join(" "))); // NoBondPt
  167. }
  168. // 调整列宽和行高
  169. mergedTable->resizeColumnsToContents();
  170. mergedTable->resizeRowsToContents();
  171. m_isInitializing = false;// 开启信号处理
  172. }
  173. void WaferProgramPage::addRow() {
  174. m_isInitializing = true;
  175. idIsUsedMap.clear();
  176. for (const auto& wafer : m_VecWaferMatrix) {
  177. idIsUsedMap[wafer.MatrixId] = true;
  178. }
  179. int row = mergedTable->rowCount();
  180. mergedTable->insertRow(row);
  181. int newId = 1;
  182. bool idUsed = true;
  183. //// 检查当前 MatrixId 是否已存在
  184. //while (idUsed) {
  185. // idUsed = false; // 假设 ID 没有被使用
  186. // // 如果 ID 已存在于 map 中,则说明已被使用
  187. // if (idIsUsedMap.find(newId) != idIsUsedMap.end()) {
  188. // idUsed = true;
  189. // }
  190. // if (idUsed) {
  191. // ++newId; // 如果 ID 被使用,检查下一个 ID
  192. // }
  193. //}
  194. //找出最大的ID值
  195. UINT maxId = 0;
  196. for (PROGRAM_WAFER_MATRIX_STRUCT& bondMatrix : m_VecWaferMatrix)
  197. {
  198. if (bondMatrix.MatrixId > maxId)
  199. {
  200. maxId = bondMatrix.MatrixId;
  201. }
  202. }
  203. newId = ++maxId;
  204. // 为新行添加默认数据
  205. mergedTable->setItem(row, 0, new QTableWidgetItem(QString::number(newId))); // MatrixID 默认值为 0
  206. mergedTable->setItem(row, 1, new QTableWidgetItem("1")); // MatrixRow 默认值为 1
  207. mergedTable->setItem(row, 2, new QTableWidgetItem("1")); // MatrixCol 默认值为 1
  208. mergedTable->setItem(row, 3, new QTableWidgetItem("0")); // LeftTopPoint_Y 默认值为 0
  209. mergedTable->setItem(row, 4, new QTableWidgetItem("0")); // LeftTopPoint_X 默认值为 0
  210. mergedTable->setItem(row, 5, new QTableWidgetItem("0")); // RightTopPoint_X 默认值为 0
  211. mergedTable->setItem(row, 6, new QTableWidgetItem("0")); // RightTopPoint_Y 默认值为 0
  212. mergedTable->setItem(row, 7, new QTableWidgetItem("0")); // RightBottomPoint_X 默认值为 0
  213. mergedTable->setItem(row, 8, new QTableWidgetItem("0")); // RightBottomPoint_Y 默认值为 0
  214. mergedTable->setItem(row, 9, new QTableWidgetItem("0")); // DieMatrixId 默认值为 0
  215. /*QComboBox* comboBox = createDieMatrixIdComboBox(0, row);
  216. mergedTable->setCellWidget(row, 9, comboBox);*/
  217. mergedTable->setItem(row, 10, new QTableWidgetItem("")); // NoBondPt 默认值为空
  218. // 同时更新 PROGRAM_WAFER_MATRIX_STRUCT 数据
  219. PROGRAM_WAFER_MATRIX_STRUCT newMatrix;
  220. newMatrix.MatrixId = newId;
  221. newMatrix.MatrixRow = 1;
  222. newMatrix.MatrixCol = 1;
  223. newMatrix.LeftTopPoint = { 0.0, 0.0 };
  224. newMatrix.RightTopPoint = { 0.0, 0.0 };
  225. newMatrix.RightBottomPoint = { 0.0, 0.0 };
  226. newMatrix.iDieMatrixId = 0;
  227. newMatrix.VecNoBondPt.clear(); // 默认值为空
  228. m_VecWaferMatrix.push_back(newMatrix);
  229. // 将新矩阵添加到数据结构中
  230. //m_pCProduct->AddWaferMatrix(newMatrix, newId);
  231. m_isInitializing = false;
  232. }
  233. void WaferProgramPage::deleteRow() {
  234. int currentRow = mergedTable->currentRow();
  235. if (currentRow >= 0 && currentRow < mergedTable->rowCount()) {
  236. // 获取 MatrixID(假设第0列是 MatrixID)
  237. QTableWidgetItem* idItem = mergedTable->item(currentRow, 0);
  238. if (!idItem) return;
  239. int matrixID = idItem->text().toInt();
  240. // 从 mergedTable 删除行
  241. mergedTable->removeRow(currentRow);
  242. // 从 m_VecWaferMatrix 中移除对应项
  243. auto it = std::remove_if(m_VecWaferMatrix.begin(), m_VecWaferMatrix.end(),
  244. [matrixID](const PROGRAM_WAFER_MATRIX_STRUCT& wafer) {
  245. return wafer.MatrixId == matrixID;
  246. });
  247. if (it != m_VecWaferMatrix.end()) {
  248. m_VecWaferMatrix.erase(it, m_VecWaferMatrix.end());
  249. }
  250. // 同时通知数据管理类删除
  251. //m_pCProduct->DeleteWaferMatrix(matrixID);
  252. }
  253. else {
  254. //QMessageBox::warning(this, "No Row Selected", "Please select a row to delete.");
  255. QMessageBox box(QMessageBox::Warning, "No Row Selected", "Please select a row to delete.");
  256. box.setStyleSheet(R"(
  257. QMessageBox {
  258. background-color: #eeeeee;
  259. color: black;
  260. }
  261. QPushButton {
  262. background-color: #dddddd;
  263. color: black;
  264. }
  265. )");
  266. box.exec();
  267. }
  268. currentRow = -1;
  269. }
  270. void WaferProgramPage::updateData() {
  271. // 1. 清空原模型中的矩阵
  272. auto originalData = m_pCProduct->GetWaferMatrix();
  273. for (const auto& matrix : originalData) {
  274. m_pCProduct->DeleteWaferMatrix(matrix.MatrixId);
  275. }
  276. // 2. 添加当前表格中的数据
  277. for (auto& matrix : m_VecWaferMatrix) {
  278. int newId = matrix.MatrixId;
  279. m_pCProduct->AddWaferMatrix(matrix, newId);
  280. auto originalData1 = m_pCProduct->GetWaferMatrix();
  281. }
  282. //qDebug() << "WaferMatrix 已同步到模型层,共同步:" << m_VecWaferMatrix.size() << "条记录。";
  283. }
  284. void WaferProgramPage::onCellChanged(int row, int column)
  285. {
  286. if (m_isInitializing) return; // 防止初始化时触发
  287. if (row >= m_VecWaferMatrix.size()) return;
  288. QTableWidgetItem* item = mergedTable->item(row, column);
  289. if (!item) return;
  290. QString value = item->text();
  291. PROGRAM_WAFER_MATRIX_STRUCT& wafer = m_VecWaferMatrix[row];
  292. switch (column) {
  293. case 0: wafer.MatrixId = value.toInt(); break;
  294. case 1: wafer.MatrixRow = value.toInt(); break;
  295. case 2: wafer.MatrixCol = value.toInt(); break;
  296. case 3: wafer.LeftTopPoint.y = value.toDouble(); break;
  297. case 4: wafer.LeftTopPoint.x = value.toDouble(); break;
  298. case 5: wafer.RightTopPoint.x = value.toDouble(); break;
  299. case 6: wafer.RightTopPoint.y = value.toDouble(); break;
  300. case 7: wafer.RightBottomPoint.x = value.toDouble(); break;
  301. case 8: wafer.RightBottomPoint.y = value.toDouble(); break;
  302. ////case 9: wafer.iDieMatrixId = value.toInt(); break;
  303. case 10: {
  304. wafer.VecNoBondPt.clear();
  305. QRegularExpression regex(R"(\((\d+),(\d+)\))");
  306. QRegularExpressionMatchIterator i = regex.globalMatch(value);
  307. while (i.hasNext()) {
  308. auto match = i.next();
  309. XY_LONG_STRUCT pt;
  310. pt.x = match.captured(1).toInt();
  311. pt.y = match.captured(2).toInt();
  312. wafer.VecNoBondPt.push_back(pt);
  313. }
  314. break;
  315. }
  316. default: break;
  317. }
  318. }
  319. // 构造函数实现
  320. NoBondPtEditDialog::NoBondPtEditDialog(int rows, int cols, const std::vector<XY_LONG_STRUCT>& selectedPts, QWidget* parent)
  321. : QDialog(parent)
  322. {
  323. this->setStyleSheet(R"(
  324. QDialog {
  325. background-color: #f0f0f0;
  326. color: black;
  327. }
  328. QPushButton {
  329. background-color: white;
  330. color: black;
  331. border: 1px solid gray;
  332. border-radius: 4px;
  333. }
  334. QPushButton:hover {
  335. background-color: #e0e0e0;
  336. }
  337. )");
  338. QVBoxLayout* mainLayout = new QVBoxLayout(this);
  339. QGridLayout* gridLayout = new QGridLayout();
  340. // 初始化已选点集合
  341. for (const auto& pt : selectedPts) {
  342. selectedSet.insert({ pt.x, pt.y });
  343. }
  344. for (int r = 0; r < rows; ++r) {
  345. for (int c = 0; c < cols; ++c) {
  346. QPushButton* btn = new QPushButton(QString("%1,%2").arg(r).arg(c));
  347. btn->setFixedSize(40, 30);
  348. QPair<int, int> pos(r, c);
  349. buttonMap[btn] = pos;
  350. bool selected = selectedSet.contains(pos);
  351. btn->setStyleSheet(selected ? "background-color: gray;" : "background-color: lightgreen;");
  352. connect(btn, &QPushButton::clicked, this, [=]() {
  353. if (selectedSet.contains(pos)) {
  354. selectedSet.remove(pos);
  355. btn->setStyleSheet("background-color: lightgreen;");
  356. }
  357. else {
  358. selectedSet.insert(pos);
  359. btn->setStyleSheet("background-color: gray;");
  360. }
  361. });
  362. gridLayout->addWidget(btn, r, c);
  363. }
  364. }
  365. mainLayout->addLayout(gridLayout);
  366. // 底部按钮
  367. QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  368. connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
  369. connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
  370. mainLayout->addWidget(buttons);
  371. }
  372. // 获取选中的点
  373. QVector<XY_LONG_STRUCT> NoBondPtEditDialog::getSelectedPoints() const {
  374. QVector<XY_LONG_STRUCT> result;
  375. for (const auto& pos : selectedSet) {
  376. XY_LONG_STRUCT pt;
  377. pt.x = pos.first;
  378. pt.y = pos.second;
  379. result.append(pt);
  380. }
  381. return result;
  382. }
  383. void NoBondPtEditDialog::mousePressEvent(QMouseEvent* event) {
  384. if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) {
  385. dragStart = event->pos();
  386. dragButton = event->button(); // 记录当前拖动按钮
  387. if (!rubberBand)
  388. rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
  389. rubberBand->setGeometry(QRect(dragStart, QSize()));
  390. rubberBand->show();
  391. isDragging = true;
  392. }
  393. }
  394. void NoBondPtEditDialog::mouseMoveEvent(QMouseEvent* event) {
  395. if (isDragging && rubberBand) {
  396. rubberBand->setGeometry(QRect(dragStart, event->pos()).normalized());
  397. }
  398. }
  399. void NoBondPtEditDialog::mouseReleaseEvent(QMouseEvent* event) {
  400. if (!rubberBand || !isDragging || event->button() != dragButton) return;
  401. rubberBand->hide();
  402. QRect selectionRect = rubberBand->geometry();
  403. for (auto it = buttonMap.begin(); it != buttonMap.end(); ++it) {
  404. QPushButton* btn = it.key();
  405. QPair<int, int> pos = it.value();
  406. if (btn->geometry().intersects(selectionRect)) {
  407. if (dragButton == Qt::LeftButton) {
  408. // toggle:如果选中就取消,否则加入
  409. if (selectedSet.contains(pos)) {
  410. selectedSet.remove(pos);
  411. btn->setStyleSheet("background-color: lightgreen;");
  412. }
  413. else {
  414. selectedSet.insert(pos);
  415. btn->setStyleSheet("background-color: gray;");
  416. }
  417. }
  418. else if (dragButton == Qt::RightButton) {
  419. // 强制取消
  420. selectedSet.remove(pos);
  421. btn->setStyleSheet("background-color: lightgreen;");
  422. }
  423. }
  424. }
  425. isDragging = false;
  426. dragButton = Qt::NoButton;
  427. }