#include "WaferProgramPage.h" std::unordered_map WaferProgramPage::idIsUsedMap; WaferProgramPage::WaferProgramPage(QWidget* parent) : QWidget(parent) { QVBoxLayout* mainLayout = new QVBoxLayout(this); m_pCProduct = CManageDB::GetInstance()->GetCProduct(); // 从数据库中加载数据 m_pCProduct->LoadDataByDB(); // 创建表格 mergedTable = new QTableWidget(this); mergedTable->setColumnCount(11); // 11 列,包含 Matrix 和 DieMatrix 的所有字段 mergedTable->setHorizontalHeaderLabels({ "MatrixID", "MatrixRow", "MatrixCol", "LeftTopPoint_Y", "LeftTopPoint_X", "RightTopPoint_X", "RightTopPoint_Y", "RightBottomPoint_X", "RightBottomPoint_Y", "DieMatrixId", "NoBondPt" }); mergedTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // 创建按钮布局 QHBoxLayout* buttonLayout = new QHBoxLayout(); QPushButton* addRowButton = new QPushButton("Add", this); QPushButton* deleteRowButton = new QPushButton("Delete", this); QPushButton* updateButton = new QPushButton("Update", this); buttonLayout->addWidget(addRowButton); buttonLayout->addWidget(deleteRowButton); buttonLayout->addWidget(updateButton); QString buttonStyle = R"( QPushButton { background-color: #f0f0f0; border: 1px solid #b0b0b0; border-radius: 4px; padding: 4px 12px; } QPushButton:hover { background-color: #e0e0ff; } QPushButton:pressed { background-color: #d0d0ff; } )"; addRowButton->setStyleSheet(buttonStyle); deleteRowButton->setStyleSheet(buttonStyle); updateButton->setStyleSheet(buttonStyle); // 将控件添加到布局 mainLayout->addWidget(mergedTable); mainLayout->addLayout(buttonLayout); setLayout(mainLayout); // 连接按钮和槽 connect(addRowButton, &QPushButton::clicked, this, &WaferProgramPage::addRow); connect(deleteRowButton, &QPushButton::clicked, this, &WaferProgramPage::deleteRow); connect(updateButton, &QPushButton::clicked, this, &WaferProgramPage::updateData); connect(mergedTable, &QTableWidget::cellChanged, this, &WaferProgramPage::onCellChanged); connect(mergedTable, &QTableWidget::cellDoubleClicked, this, [=](int row, int column) { if (column == 9) { QComboBox* comboBox = createDieMatrixIdComboBox(m_VecWaferMatrix[row].iDieMatrixId, row); mergedTable->setCellWidget(row, column, comboBox); comboBox->showPopup(); // 可选:自动展开下拉 // 记录初始值(以防没有变化) int originalValue = comboBox->currentData().toInt(); // 1. 用户选择后立即还原 connect(comboBox, QOverload::of(&QComboBox::activated), this, [=](int index) { int selectedId = comboBox->itemData(index).toInt(); m_VecWaferMatrix[row].iDieMatrixId = selectedId; mergedTable->removeCellWidget(row, column); mergedTable->setItem(row, column, new QTableWidgetItem(QString::number(selectedId))); }); // 2. 用户没有选中,仅点击其他地方,触发还原 connect(comboBox, &QComboBox::hidePopup, this, [=]() { // 如果还在表格里,就还原(防止重复) if (mergedTable->cellWidget(row, column) == comboBox) { int selectedId = comboBox->currentData().toInt(); m_VecWaferMatrix[row].iDieMatrixId = selectedId; mergedTable->removeCellWidget(row, column); mergedTable->setItem(row, column, new QTableWidgetItem(QString::number(selectedId))); } }); } }); connect(mergedTable, &QTableWidget::cellDoubleClicked, this, [=](int row, int column) { if (column == 10) { // NoBondPt 列 const auto& wafer = m_VecWaferMatrix[row]; NoBondPtEditDialog dlg(wafer.MatrixRow, wafer.MatrixCol, wafer.VecNoBondPt, this); if (dlg.exec() == QDialog::Accepted) { // 获取用户选择结果 QVector selected = dlg.getSelectedPoints(); // 更新数据结构 m_VecWaferMatrix[row].VecNoBondPt.clear(); for (const auto& pt : selected) { m_VecWaferMatrix[row].VecNoBondPt.push_back(pt); } // 转换为字符串填入表格 QStringList ptList; for (const auto& pt : selected) { ptList << QString("(%1,%2)").arg(pt.x).arg(pt.y); } mergedTable->setItem(row, column, new QTableWidgetItem(ptList.join(" "))); } } }); // 初始化表格数据 initMergedData(); } //QWidget* WaferProgramPage::CreateWaferProgramPage(const CONFIG_BASE_STRUCT& control) { // return new WaferProgramPage(); //} //创建下拉列表 QComboBox* WaferProgramPage::createDieMatrixIdComboBox(int defaultId, int row) { QComboBox* comboBox = new QComboBox(mergedTable); // 设置样式,确保在暗色模式下也是白底黑字 comboBox->setStyleSheet(R"( QComboBox { background-color: white; color: black; border: 1px solid #BABBDC; border-radius: 4px; padding: 2px 5px; } QComboBox QAbstractItemView { background-color: white; color: black; selection-background-color: #E5E5FF; selection-color: black; } )"); for (const auto& dieMatrix : m_VecDieMatrixt) { /*comboBox->addItem( QString("%1 - %2").arg(dieMatrix.MatrixId).arg(QString::fromStdString(dieMatrix.strModuleName)), QVariant(dieMatrix.MatrixId) );*/ comboBox->addItem(QString::number(dieMatrix.MatrixId), QVariant(dieMatrix.MatrixId)); } int index = comboBox->findData(defaultId); if (index >= 0) comboBox->setCurrentIndex(index); return comboBox; } void WaferProgramPage::initMergedData() { m_isInitializing = true; SqlOperation& sqlOp = SqlOperation::GetInstance(); QList directories; int userPrivilege = 0;//? sqlOp.GetDirectories("Dir_Programme", userPrivilege, directories); // 使用相应的表名和权限加载目录 m_VecWaferMatrix = m_pCProduct->GetWaferMatrix(); for (const PROGRAM_WAFER_MATRIX_STRUCT& wafer : m_VecWaferMatrix) { int row = mergedTable->rowCount(); mergedTable->insertRow(row); PROGRAM_DIE_MATRIX_STRUCT stDieMatrix; m_pCProduct->GetDieMatrix(wafer.MatrixId, stDieMatrix); m_VecDieMatrixt.push_back(stDieMatrix); // 填充表格数据 mergedTable->setItem(row, 0, new QTableWidgetItem(QString::number(wafer.MatrixId))); // MatrixID mergedTable->setItem(row, 1, new QTableWidgetItem(QString::number(wafer.MatrixRow))); // MatrixRow mergedTable->setItem(row, 2, new QTableWidgetItem(QString::number(wafer.MatrixCol))); // MatrixCol mergedTable->setItem(row, 3, new QTableWidgetItem(QString::number(wafer.LeftTopPoint.y))); // LeftTopPoint_Y mergedTable->setItem(row, 4, new QTableWidgetItem(QString::number(wafer.LeftTopPoint.x))); // LeftTopPoint_X mergedTable->setItem(row, 5, new QTableWidgetItem(QString::number(wafer.RightTopPoint.x))); // RightTopPoint_X mergedTable->setItem(row, 6, new QTableWidgetItem(QString::number(wafer.RightTopPoint.y))); // RightTopPoint_Y mergedTable->setItem(row, 7, new QTableWidgetItem(QString::number(wafer.RightBottomPoint.x))); // RightBottomPoint_X mergedTable->setItem(row, 8, new QTableWidgetItem(QString::number(wafer.RightBottomPoint.y))); // RightBottomPoint_Y mergedTable->setItem(row, 9, new QTableWidgetItem(QString::number(wafer.iDieMatrixId))); // DieMatrixId // 填充 NoBondPt 数据 QStringList noBondPts; for (const XY_LONG_STRUCT& pt : wafer.VecNoBondPt) { noBondPts.append(QString("(%1,%2)").arg(pt.x).arg(pt.y)); } mergedTable->setItem(row, 10, new QTableWidgetItem(noBondPts.join(" "))); // NoBondPt } // 调整列宽和行高 mergedTable->resizeColumnsToContents(); mergedTable->resizeRowsToContents(); m_isInitializing = false;// 开启信号处理 } void WaferProgramPage::addRow() { m_isInitializing = true; idIsUsedMap.clear(); for (const auto& wafer : m_VecWaferMatrix) { idIsUsedMap[wafer.MatrixId] = true; } int row = mergedTable->rowCount(); mergedTable->insertRow(row); int newId = 1; bool idUsed = true; //// 检查当前 MatrixId 是否已存在 //while (idUsed) { // idUsed = false; // 假设 ID 没有被使用 // // 如果 ID 已存在于 map 中,则说明已被使用 // if (idIsUsedMap.find(newId) != idIsUsedMap.end()) { // idUsed = true; // } // if (idUsed) { // ++newId; // 如果 ID 被使用,检查下一个 ID // } //} //找出最大的ID值 UINT maxId = 0; for (PROGRAM_WAFER_MATRIX_STRUCT& bondMatrix : m_VecWaferMatrix) { if (bondMatrix.MatrixId > maxId) { maxId = bondMatrix.MatrixId; } } newId = ++maxId; // 为新行添加默认数据 mergedTable->setItem(row, 0, new QTableWidgetItem(QString::number(newId))); // MatrixID 默认值为 0 mergedTable->setItem(row, 1, new QTableWidgetItem("1")); // MatrixRow 默认值为 1 mergedTable->setItem(row, 2, new QTableWidgetItem("1")); // MatrixCol 默认值为 1 mergedTable->setItem(row, 3, new QTableWidgetItem("0")); // LeftTopPoint_Y 默认值为 0 mergedTable->setItem(row, 4, new QTableWidgetItem("0")); // LeftTopPoint_X 默认值为 0 mergedTable->setItem(row, 5, new QTableWidgetItem("0")); // RightTopPoint_X 默认值为 0 mergedTable->setItem(row, 6, new QTableWidgetItem("0")); // RightTopPoint_Y 默认值为 0 mergedTable->setItem(row, 7, new QTableWidgetItem("0")); // RightBottomPoint_X 默认值为 0 mergedTable->setItem(row, 8, new QTableWidgetItem("0")); // RightBottomPoint_Y 默认值为 0 mergedTable->setItem(row, 9, new QTableWidgetItem("0")); // DieMatrixId 默认值为 0 /*QComboBox* comboBox = createDieMatrixIdComboBox(0, row); mergedTable->setCellWidget(row, 9, comboBox);*/ mergedTable->setItem(row, 10, new QTableWidgetItem("")); // NoBondPt 默认值为空 // 同时更新 PROGRAM_WAFER_MATRIX_STRUCT 数据 PROGRAM_WAFER_MATRIX_STRUCT newMatrix; newMatrix.MatrixId = newId; newMatrix.MatrixRow = 1; newMatrix.MatrixCol = 1; newMatrix.LeftTopPoint = { 0.0, 0.0 }; newMatrix.RightTopPoint = { 0.0, 0.0 }; newMatrix.RightBottomPoint = { 0.0, 0.0 }; newMatrix.iDieMatrixId = 0; newMatrix.VecNoBondPt.clear(); // 默认值为空 m_VecWaferMatrix.push_back(newMatrix); // 将新矩阵添加到数据结构中 //m_pCProduct->AddWaferMatrix(newMatrix, newId); m_isInitializing = false; } void WaferProgramPage::deleteRow() { int currentRow = mergedTable->currentRow(); if (currentRow >= 0 && currentRow < mergedTable->rowCount()) { // 获取 MatrixID(假设第0列是 MatrixID) QTableWidgetItem* idItem = mergedTable->item(currentRow, 0); if (!idItem) return; int matrixID = idItem->text().toInt(); // 从 mergedTable 删除行 mergedTable->removeRow(currentRow); // 从 m_VecWaferMatrix 中移除对应项 auto it = std::remove_if(m_VecWaferMatrix.begin(), m_VecWaferMatrix.end(), [matrixID](const PROGRAM_WAFER_MATRIX_STRUCT& wafer) { return wafer.MatrixId == matrixID; }); if (it != m_VecWaferMatrix.end()) { m_VecWaferMatrix.erase(it, m_VecWaferMatrix.end()); } // 同时通知数据管理类删除 //m_pCProduct->DeleteWaferMatrix(matrixID); } else { //QMessageBox::warning(this, "No Row Selected", "Please select a row to delete."); QMessageBox box(QMessageBox::Warning, "No Row Selected", "Please select a row to delete."); box.setStyleSheet(R"( QMessageBox { background-color: #eeeeee; color: black; } QPushButton { background-color: #dddddd; color: black; } )"); box.exec(); } currentRow = -1; } void WaferProgramPage::updateData() { // 1. 清空原模型中的矩阵 auto originalData = m_pCProduct->GetWaferMatrix(); for (const auto& matrix : originalData) { m_pCProduct->DeleteWaferMatrix(matrix.MatrixId); } // 2. 添加当前表格中的数据 for (auto& matrix : m_VecWaferMatrix) { int newId = matrix.MatrixId; m_pCProduct->AddWaferMatrix(matrix, newId); auto originalData1 = m_pCProduct->GetWaferMatrix(); } //qDebug() << "WaferMatrix 已同步到模型层,共同步:" << m_VecWaferMatrix.size() << "条记录。"; } void WaferProgramPage::onCellChanged(int row, int column) { if (m_isInitializing) return; // 防止初始化时触发 if (row >= m_VecWaferMatrix.size()) return; QTableWidgetItem* item = mergedTable->item(row, column); if (!item) return; QString value = item->text(); PROGRAM_WAFER_MATRIX_STRUCT& wafer = m_VecWaferMatrix[row]; switch (column) { case 0: wafer.MatrixId = value.toInt(); break; case 1: wafer.MatrixRow = value.toInt(); break; case 2: wafer.MatrixCol = value.toInt(); break; case 3: wafer.LeftTopPoint.y = value.toDouble(); break; case 4: wafer.LeftTopPoint.x = value.toDouble(); break; case 5: wafer.RightTopPoint.x = value.toDouble(); break; case 6: wafer.RightTopPoint.y = value.toDouble(); break; case 7: wafer.RightBottomPoint.x = value.toDouble(); break; case 8: wafer.RightBottomPoint.y = value.toDouble(); break; ////case 9: wafer.iDieMatrixId = value.toInt(); break; case 10: { wafer.VecNoBondPt.clear(); QRegularExpression regex(R"(\((\d+),(\d+)\))"); QRegularExpressionMatchIterator i = regex.globalMatch(value); while (i.hasNext()) { auto match = i.next(); XY_LONG_STRUCT pt; pt.x = match.captured(1).toInt(); pt.y = match.captured(2).toInt(); wafer.VecNoBondPt.push_back(pt); } break; } default: break; } } // 构造函数实现 NoBondPtEditDialog::NoBondPtEditDialog(int rows, int cols, const std::vector& selectedPts, QWidget* parent) : QDialog(parent) { this->setStyleSheet(R"( QDialog { background-color: #f0f0f0; color: black; } QPushButton { background-color: white; color: black; border: 1px solid gray; border-radius: 4px; } QPushButton:hover { background-color: #e0e0e0; } )"); QVBoxLayout* mainLayout = new QVBoxLayout(this); QGridLayout* gridLayout = new QGridLayout(); // 初始化已选点集合 for (const auto& pt : selectedPts) { selectedSet.insert({ pt.x, pt.y }); } for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { QPushButton* btn = new QPushButton(QString("%1,%2").arg(r).arg(c)); btn->setFixedSize(40, 30); QPair pos(r, c); buttonMap[btn] = pos; bool selected = selectedSet.contains(pos); btn->setStyleSheet(selected ? "background-color: gray;" : "background-color: lightgreen;"); connect(btn, &QPushButton::clicked, this, [=]() { if (selectedSet.contains(pos)) { selectedSet.remove(pos); btn->setStyleSheet("background-color: lightgreen;"); } else { selectedSet.insert(pos); btn->setStyleSheet("background-color: gray;"); } }); gridLayout->addWidget(btn, r, c); } } mainLayout->addLayout(gridLayout); // 底部按钮 QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); mainLayout->addWidget(buttons); } // 获取选中的点 QVector NoBondPtEditDialog::getSelectedPoints() const { QVector result; for (const auto& pos : selectedSet) { XY_LONG_STRUCT pt; pt.x = pos.first; pt.y = pos.second; result.append(pt); } return result; } void NoBondPtEditDialog::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) { dragStart = event->pos(); dragButton = event->button(); // 记录当前拖动按钮 if (!rubberBand) rubberBand = new QRubberBand(QRubberBand::Rectangle, this); rubberBand->setGeometry(QRect(dragStart, QSize())); rubberBand->show(); isDragging = true; } } void NoBondPtEditDialog::mouseMoveEvent(QMouseEvent* event) { if (isDragging && rubberBand) { rubberBand->setGeometry(QRect(dragStart, event->pos()).normalized()); } } void NoBondPtEditDialog::mouseReleaseEvent(QMouseEvent* event) { if (!rubberBand || !isDragging || event->button() != dragButton) return; rubberBand->hide(); QRect selectionRect = rubberBand->geometry(); for (auto it = buttonMap.begin(); it != buttonMap.end(); ++it) { QPushButton* btn = it.key(); QPair pos = it.value(); if (btn->geometry().intersects(selectionRect)) { if (dragButton == Qt::LeftButton) { // toggle:如果选中就取消,否则加入 if (selectedSet.contains(pos)) { selectedSet.remove(pos); btn->setStyleSheet("background-color: lightgreen;"); } else { selectedSet.insert(pos); btn->setStyleSheet("background-color: gray;"); } } else if (dragButton == Qt::RightButton) { // 强制取消 selectedSet.remove(pos); btn->setStyleSheet("background-color: lightgreen;"); } } } isDragging = false; dragButton = Qt::NoButton; }