From 904e91a90352910e341182435c7d23bbf72d2860 Mon Sep 17 00:00:00 2001 From: chenchaohong <15927339605@139.com> Date: Fri, 6 Dec 2024 16:23:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=90=AF=E5=8A=A8=E5=8F=AA?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=9C=80=E6=96=B0=E6=89=B9=E6=AC=A1=EF=BC=8C?= =?UTF-8?q?=E5=85=B6=E4=BB=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PreVerify/DefectViewCustom.cpp | 6 +- PreVerify/DefectViewCustom.h | 2 +- PreVerify/PreVerifyWidget.cpp | 566 ++++++++++++++++----------------- PreVerify/PreVerifyWidget.h | 64 ++-- PreVerify/main.cpp | 4 +- README.txt | 0 6 files changed, 318 insertions(+), 324 deletions(-) create mode 100644 README.txt diff --git a/PreVerify/DefectViewCustom.cpp b/PreVerify/DefectViewCustom.cpp index 8d6c3c3..572947f 100644 --- a/PreVerify/DefectViewCustom.cpp +++ b/PreVerify/DefectViewCustom.cpp @@ -43,7 +43,7 @@ DefectViewCustom::DefectViewCustom(QWidget* parent) { } -void DefectViewCustom::load(QString filePath, int defectId, bool isValid, double x, double y, QString jobLayer, QPixmap& samplePxmp, int defectType, int rowHeight, bool containSample) { +void DefectViewCustom::load(QString filePath, int defectId, bool isValid, double x, double y, int defectType, int rowHeight, struct BoardDetail& boardDetail) { this->setFixedHeight(rowHeight); m_isValidBtn.setGeometry(this->geometry()); //加载扫描图 @@ -54,10 +54,12 @@ void DefectViewCustom::load(QString filePath, int defectId, bool isValid, double m_scanPxmpItem.setPixmap(*scanPxmp); m_scanPxmpItem.setPos(0, 0); - if (containSample) { + if (boardDetail.hasCam) { //加载参考图 double pixSize = 15.937359904903442; double xx = x / pixSize; + QPixmap samplePxmp; + QPixmapCache::find(boardDetail.jobLayer, &samplePxmp); double yy = samplePxmp.height() - y / pixSize; QPixmap copy = samplePxmp.copy(QRect(xx - width / 2, yy - height / 2, width, height)); copy = copy.scaled(200, 200, Qt::KeepAspectRatio); diff --git a/PreVerify/DefectViewCustom.h b/PreVerify/DefectViewCustom.h index 6c4b45e..03a8fbc 100644 --- a/PreVerify/DefectViewCustom.h +++ b/PreVerify/DefectViewCustom.h @@ -28,7 +28,7 @@ private: public: DefectViewCustom(QWidget* parent = nullptr); - void load(QString filePath, int defectId, bool isValid, double x, double y, QString jobLayer, QPixmap& samplePxmp, int defectType, int rowHeight, bool containSample); + void load(QString filePath, int defectId, bool isValid, double x, double y, int defectType, int rowHeight, struct BoardDetail& boardDetail); void hideCam(int state); void wheelEvent(QWheelEvent* e) override; void mouseMoveEvent(QMouseEvent* event) override; diff --git a/PreVerify/PreVerifyWidget.cpp b/PreVerify/PreVerifyWidget.cpp index 34e79b3..07c95b9 100644 --- a/PreVerify/PreVerifyWidget.cpp +++ b/PreVerify/PreVerifyWidget.cpp @@ -19,17 +19,23 @@ #include "QtConcurrent/qtconcurrentrun.h" #include "QFutureWatcher" #include "DefectViewCustom.h" +#include "QTimer" +#include PreVerifyWidget::PreVerifyWidget(QWidget* parent) { QImageReader::setAllocationLimit(0); QPixmapCache::setCacheLimit(8 * 1024 * 1024); + m_boardItemList = new QList(); setUi(); setConnection(); readDefectTypesDesc(); - load(); - filter(); loadDate(); + loadTreeWgt(); + m_treeWgt.setExpandsOnDoubleClick(true); + m_treeWgt.setAutoExpandDelay(0); + m_showDefectCountCmb.setCurrentIndex(3); + showDefectCountCmbIndexChanged(); } void PreVerifyWidget::setUi() { @@ -37,61 +43,19 @@ void PreVerifyWidget::setUi() { m_lt.addLayout(&m_leftLt, 3); m_lt.addLayout(&m_rightLt, 11); - labelY.setText("年"); - labelM.setText("月"); - labelD.setText("日"); - - m_spinY.setMaximum(3000); - m_spinY.setFixedWidth(70); - m_spinY.setMinimum(1900); - m_spinY.setValue(QDate::currentDate().year()); - m_spinM.setMaximum(12); - m_spinM.setMinimum(1); - m_spinM.setFixedWidth(40); - m_spinM.setValue(QDate::currentDate().month()); - m_spinD.setMaximum(31); - m_spinD.setMinimum(1); - m_spinD.setFixedWidth(40); - m_spinD.setValue(QDate::currentDate().day()); - m_dateLt.addWidget(&m_spinY); - m_dateLt.addWidget(&labelY); - m_dateLt.addWidget(&m_yearClearBtn); - m_dateLt.addWidget(&m_spinM); - m_dateLt.addWidget(&labelM); - m_dateLt.addWidget(&m_monthClearBtn); - m_dateLt.addWidget(&m_spinD); - m_dateLt.addWidget(&labelD); - m_dateLt.addWidget(&m_dateClearBtn); - - label1.setText("批号:"); - label11.setText("批号:"); label2.setText("板号:"); label3.setText("料号:"); label4.setText("层号:"); - label1.setFixedWidth(30); - label11.setFixedWidth(30); - m_yearClearBtn.setFixedWidth(25); - m_monthClearBtn.setFixedWidth(25); - m_dateClearBtn.setFixedWidth(25); - //m_leftLt.addWidget(&label1, 0, 0); - //m_leftLt.addLayout(&m_dateLt, 0, 1, 1, 2); - m_leftLt.addWidget(&label11, 1, 0); - m_leftLt.addWidget(&m_dateCmb, 1, 1, 1, 2); + m_leftLt.addWidget(&label1, 1, 0); + m_leftLt.addWidget(&m_dateCmb, 1, 1, 1, 4); m_leftLt.addWidget(&label2, 2, 0); - m_leftLt.addWidget(&m_boardIdEdt, 2, 1, 1, 2); + m_leftLt.addWidget(&m_boardIdEdt, 2, 1, 1, 4); m_leftLt.addWidget(&label3, 3, 0); - m_leftLt.addWidget(&m_jobEdt, 3, 1, 1, 2); + m_leftLt.addWidget(&m_jobEdt, 3, 1, 1, 4); m_leftLt.addWidget(&label4, 4, 0); - m_leftLt.addWidget(&m_layerEdt, 4, 1, 1, 2); - m_leftLt.addWidget(&m_treeWgt, 5, 0, 1, 3); - - m_dateEdt.setCalendarPopup(true); - m_dateEdt.setDate(QDate::currentDate()); - m_dateEdt.setDisplayFormat("yyyy-MM-dd"); - m_yearClearBtn.setIcon(QIcon(":/res/ico/dateClear.png")); - m_monthClearBtn.setIcon(QIcon(":/res/ico/dateClear.png")); - m_dateClearBtn.setIcon(QIcon(":/res/ico/dateClear.png")); + m_leftLt.addWidget(&m_layerEdt, 4, 1, 1, 4); + m_leftLt.addWidget(&m_treeWgt, 5, 0, 1, 5); m_pageBtnLt.addWidget(&m_lastBoardBtn); m_pageBtnLt.addWidget(&m_lastDefectBtn); @@ -125,7 +89,6 @@ void PreVerifyWidget::setUi() { m_showDefectCountCmb.addItem(" 1 x 3"); m_showDefectCountCmb.addItem(" 2 x 4"); m_showDefectCountCmb.addItem(" 2 x 5"); - m_showDefectCountCmb.setCurrentIndex(3); m_rightLt.addLayout(&m_pageBtnLt); m_rightLt.addWidget(&m_grdScr); @@ -143,12 +106,11 @@ void PreVerifyWidget::setUi() { m_grdLt.setAlignment(Qt::AlignLeft | Qt::AlignTop); - QStringList treeHeaders; - treeHeaders << "料号/层号" << "板号" << "A/B面" << "有效/总缺陷"; + QStringList treeHeaders = { "料号/层号" , "板号" , "A/B面" , "有效/总缺陷" }; m_treeWgt.setIndentation(5); m_treeWgt.setColumnCount(treeHeaders.size()); m_treeWgt.setHeaderLabels(treeHeaders); - m_treeWgt.setColumnWidth(0, 200); + m_treeWgt.setColumnWidth(0, 150); m_treeWgt.setColumnWidth(1, 45); m_treeWgt.setColumnWidth(2, 30); m_treeWgt.setColumnWidth(3, 45); @@ -156,45 +118,7 @@ void PreVerifyWidget::setUi() { } void PreVerifyWidget::setConnection() { - QObject::connect(&m_yearClearBtn, &QPushButton::pressed, [=]() { - m_spinY.clear(); - filter(); - }); - QObject::connect(&m_monthClearBtn, &QPushButton::pressed, [=]() { - m_spinM.clear(); - filter(); - }); - QObject::connect(&m_dateClearBtn, &QPushButton::pressed, [=]() { - m_spinD.clear(); - filter(); - }); - QObject::connect(&m_spinY, &QSpinBox::valueChanged, [=]() { - filter(); - }); - QObject::connect(&m_spinY, &QSpinBox::textChanged, [=]() { - filter(); - }); - QObject::connect(&m_spinY, &QSpinBox::editingFinished, [=]() { - filter(); - }); - QObject::connect(&m_spinM, &QSpinBox::valueChanged, [=]() { - filter(); - }); - QObject::connect(&m_spinM, &QSpinBox::textChanged, [=]() { - filter(); - }); - QObject::connect(&m_spinM, &QSpinBox::editingFinished, [=]() { - filter(); - }); - QObject::connect(&m_spinD, &QSpinBox::valueChanged, [=]() { - filter(); - }); - QObject::connect(&m_spinD, &QSpinBox::textChanged, [=]() { - filter(); - }); - QObject::connect(&m_spinD, &QSpinBox::editingFinished, [=]() { - filter(); - }); + QObject::connect(&m_dateCmb, &QComboBox::currentIndexChanged, this, &PreVerifyWidget::filter); QObject::connect(&m_boardIdEdt, &QLineEdit::textChanged, [=]() { filter(); }); @@ -207,36 +131,32 @@ void PreVerifyWidget::setConnection() { QObject::connect(&m_showCamChk, &QCheckBox::stateChanged, [=](int state) { slot_treeWgtCurrentItemChanged(m_treeWgt.currentItem(), nullptr); }); - QObject::connect(&m_showDefectCountCmb, &QComboBox::currentIndexChanged, [=]() { - if (m_treeWgt.currentItem() != nullptr) { - slot_treeWgtCurrentItemChanged(m_treeWgt.currentItem(), nullptr); - } - }); - QObject::connect(&m_dateCmb, &QComboBox::currentTextChanged, [=]() { - filter(); - }); + QObject::connect(&m_showDefectCountCmb, &QComboBox::currentIndexChanged, this, &PreVerifyWidget::showDefectCountCmbIndexChanged); QObject::connect(&m_treeWgt, &QTreeWidget::currentItemChanged, this, &PreVerifyWidget::slot_treeWgtCurrentItemChanged); QObject::connect(&m_lastBoardBtn, &QPushButton::pressed, this, &PreVerifyWidget::slot_lastBoardBtnPressed); QObject::connect(&m_lastDefectBtn, &QPushButton::pressed, this, &PreVerifyWidget::slot_lastDefectBtnPressed); QObject::connect(&m_nextBoardBtn, &QPushButton::pressed, this, &PreVerifyWidget::slot_nextBoardBtnPressed); QObject::connect(&m_nextDefectBtn, &QPushButton::pressed, this, &PreVerifyWidget::slot_nextDefectBtnPressed); - QObject::connect(this, &PreVerifyWidget::sig_grdLtUpdate, this, &PreVerifyWidget::slot_grdLtUpdate); + + QObject::connect(m_grdScr.verticalScrollBar(), &QScrollBar::valueChanged, [=](int value) { + if (m_grdLt.count() < m_boardDetail.sumCount) { + getDefectImg(m_limit, m_boardDetail.sumCount); + m_grdScr.verticalScrollBar()->setValue(m_grdScr.verticalScrollBar()->singleStep()); + } + }); } void PreVerifyWidget::loadDate() { m_dateCmb.addItem(""); - QString path = "D:/PCBDataset/Defect/fengming/AOI_DEFECT"; - QDir rootDir(path); - QStringList dateList = rootDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs, QDir::Time); + QStringList dateList = QDir(AOI_DEFECT).entryList(QDir::NoDotAndDotDot | QDir::AllDirs, QDir::Time); for (QString date : dateList) { m_dateCmb.addItem(date); } } void PreVerifyWidget::showDefectCountCmbIndexChanged() { - int ix = m_showDefectCountCmb.currentIndex(); - switch (ix) { + switch (m_showDefectCountCmb.currentIndex()) { case 0: m_rowCount = 1; m_colCount = 2; @@ -260,125 +180,130 @@ void PreVerifyWidget::showDefectCountCmbIndexChanged() { default: break; } + slot_treeWgtCurrentItemChanged(m_currentItem, m_currentItem); } void PreVerifyWidget::readDefectTypesDesc() { - JSONDocUtil::getInstance().readJSONDoc("D:/PCBDataset/GlobalSettings/defectTypeDescription.json", m_defectTypesDescJson); + JSONDocUtil::getInstance().readJSONDoc(DEFECTTYPEDESCRIPTION_JSON, m_defectTypesDescJson); } QString PreVerifyWidget::defectId2Desc(int defectId) { return m_defectTypesDescJson.value(QString::number(defectId)).toObject().value("cn").toString(); } -void PreVerifyWidget::load() { - loadTreeWgt(); -} - void PreVerifyWidget::loadTreeWgt() { m_treeWgt.clear(); - QString path = "D:/PCBDataset/Defect/fengming/AOI_DEFECT"; - QJsonObject yearJson; - - //创建文件夹Json对象 - toJson(yearJson, path); - + QJsonObject* yearJson = new QJsonObject(); + getDateList(yearJson); //创建文件夹树 - for (QString yearKey : yearJson.keys()) { + bool firstLoadDateItem = false; + QBrush brush = QBrush(QColor("#C3FFC3")); + + QStringList years = yearJson->keys(); + std::reverse(years.begin(), years.end()); + for (QString yearKey : years) { QTreeWidgetItem* yearItem = new QTreeWidgetItem(&m_treeWgt); yearItem->setText(0, yearKey); + yearItem->setExpanded(true); - QJsonObject monthJson = yearJson.value(yearKey).toObject(); - for (QString monthKey : monthJson.keys()) { + QJsonObject monthJson = yearJson->value(yearKey).toObject(); + QStringList months = monthJson.keys(); + std::reverse(months.begin(),months.end()); + for (QString monthKey : months) { QTreeWidgetItem* monthItem = new QTreeWidgetItem(yearItem); monthItem->setText(0, monthKey); + monthItem->setExpanded(true); QJsonArray dateArr = monthJson.value(monthKey).toArray(); for (int i = 0; i < dateArr.size(); i++) { QString dateKey = dateArr.at(i).toString(); QTreeWidgetItem* dateItem = new QTreeWidgetItem(monthItem); dateItem->setText(0, dateKey); + dateItem->setExpanded(true); + m_boardItemList->push_back(dateItem); - //创建板数据 - QString datePath = path + "/" + dateKey; - QDir datDir(datePath); - QStringList boardIdList = datDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs); - for (QString boardId : boardIdList) { - bool isInt = true; - boardId.toInt(&isInt); - if (!isInt) { - continue; - } - QString boardIdPath = datePath + "/" + boardId; - - for (char i = 'A'; i <= 'B'; i++) { - QTreeWidgetItem* item; - QString vrsPath = boardIdPath + "/" + i + ".vrs"; - - //备份 - QFile file = QFile(vrsPath); - if (file.exists()) { - file.copy(boardIdPath + "/" + i + "I.vrs"); - } - vrsPath = boardIdPath + "/" + i + "I.vrs"; - - //读数据 - if (QFile(vrsPath).exists()) { - bool hasVerify = false; - item = new QTreeWidgetItem(dateItem); - - QJsonObject obj; - JSONDocUtil::getInstance().readJSONDoc(vrsPath, obj); - QString job = obj.value("Job").toString(); - QString layer = obj.value("Layer").toString(); - int count = obj.value("Count").toInt(); - - item->setText(0, job + "/" + layer); - item->setText(1, boardId); - item->setText(2, vrsPath.mid(vrsPath.size() - 6, 1)); - - //读有效缺陷数 - int validSum = getValid(obj , hasVerify); - item->setText(3, QString::number(validSum) + "/" + QString::number(count)); - if (hasVerify) { - QBrush brush = QBrush(QColor("#C3FFC3")); - item->setBackground(0, brush); - item->setBackground(1, brush); - item->setBackground(2, brush); - item->setBackground(3, brush); - } - m_boardItemList.push_back(item); - } - } + if (!firstLoadDateItem) { + loadDateItem(dateItem); + firstLoadDateItem = true; } } } } + + delete yearJson; } -void PreVerifyWidget::toJson(QJsonObject& yearJson, QString& path) { - QDir rootDir(path); +void PreVerifyWidget::getBoardList(QString date, QList* boardList) { + QString datePath = AOI_DEFECT + "/" + date; + + QStringList boardIdList = QDir(datePath).entryList(QDir::NoDotAndDotDot | QDir::AllDirs); + for (QString boardId : boardIdList) { + bool isInt = true; + boardId.toInt(&isInt); + if (!isInt) { + continue; + } + QString boardIdPath = datePath + "/" + boardId; + + for (char i = 'A'; i <= 'B'; i++) { + QString vrsPath = boardIdPath + "/" + i + ".vrs"; + + //备份 + QFile file = QFile(vrsPath); + if (file.exists()) { + file.copy(boardIdPath + "/" + i + "I.vrs"); + } + vrsPath = boardIdPath + "/" + i + "I.vrs"; + + //读数据 + if (QFile(vrsPath).exists()) { + bool hasVerify = false; + BoardDetail* boardDetail = new BoardDetail(); + + QJsonObject obj; + JSONDocUtil::getInstance().readJSONDoc(vrsPath, obj); + QString job = obj.value("Job").toString(); + QString layer = obj.value("Layer").toString(); + int count = obj.value("Count").toInt(); + + boardDetail->jobLayer = job + "/" + layer; + boardDetail->boardId = boardId; + boardDetail->side = vrsPath.mid(vrsPath.size() - 6, 1); + + //读有效缺陷数 + int validSum = getValid(obj, hasVerify); + boardDetail->validSumCount = QString::number(validSum) + "/" + QString::number(count); + boardDetail->hasVerify = hasVerify; + boardList->push_back(boardDetail); + } + } + } +} + +void PreVerifyWidget::getDateList(QJsonObject* yearJson) { + QDir rootDir(AOI_DEFECT); QStringList dateList = rootDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs, QDir::Time); for (QString dateStr : dateList) { QString yearStr = dateStr.mid(0, 4); QString monthStr = dateStr.mid(0, 7); - if (!yearJson.contains(yearStr)) { - yearJson.insert(yearStr, QJsonObject()); + if (!yearJson->contains(yearStr)) { + yearJson->insert(yearStr, QJsonObject()); } - QJsonObject monthJson = yearJson.value(yearStr).toObject(); + QJsonObject monthJson = yearJson->value(yearStr).toObject(); if (!monthJson.contains(monthStr)) { monthJson.insert(monthStr, QJsonObject()); - yearJson.insert(yearStr, monthJson); + yearJson->insert(yearStr, monthJson); } QJsonArray dateArr = monthJson.value(monthStr).toArray(); dateArr.append(dateStr); monthJson.insert(monthStr, dateArr); - yearJson.insert(yearStr, monthJson); + yearJson->insert(yearStr, monthJson); } } @@ -393,59 +318,103 @@ void PreVerifyWidget::clear() { } } -void PreVerifyWidget::slot_treeWgtCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous) { - //清理 - clear(); +void PreVerifyWidget::loadDateItem(QTreeWidgetItem* dateItem) { + if (dateItem->childCount() == 0) { + QList* list = new QList(); + getBoardList(dateItem->text(0), list); + int index = m_boardItemList->indexOf(dateItem); + for (BoardDetail* boardDetail : *list) { + QTreeWidgetItem* item = new QTreeWidgetItem(dateItem); + item->setText(0, boardDetail->jobLayer); + item->setText(1, boardDetail->boardId); + item->setText(2, boardDetail->side); + item->setText(3, boardDetail->validSumCount); + if (boardDetail->hasVerify) { + QBrush brush = QBrush(QColor("#C3FFC3")); + item->setBackground(0, brush); + item->setBackground(1, brush); + item->setBackground(2, brush); + item->setBackground(3, brush); + } + m_boardItemList->insert(++index, item); + } + qDeleteAll(*list); + list->clear(); + delete list; - if (current == nullptr || current->columnCount() == 1) { - return; + filter(); } - showDefectCountCmbIndexChanged(); - - //填充 - QString dateStr = current->parent()->text(0); - QString jobLayer = current->text(0); - QString boardId = current->text(1); - QString ab = current->text(2); - int count = current->text(3).split("/").at(1).toInt(); - - m_dirPath = "D:/PCBDataset/Defect/fengming/AOI_DEFECT/" + dateStr + "/" + boardId + "/"; - m_ab = ab; - m_curDefectLbl.setText(boardId + ":" + ab + ":" + current->text(3)); - - //缓存 Json - QString fileName = m_dirPath + m_ab + "I.vrs"; - if (QFile(fileName).exists()) { - JSONDocUtil::getInstance().readJSONDoc(fileName, m_vrsJson); - } - - QJsonArray arr = m_vrsJson.value("Defectx").toArray(); - - QString samplePath = "D:/PCBDataset/Reference/" + jobLayer + "/Learn/panel_image.png"; - if (!QPixmapCache::find(jobLayer, &m_samplePxmp)) { - m_samplePxmp.load(samplePath, nullptr, Qt::NoFormatConversion); - QPixmapCache::insert(jobLayer, m_samplePxmp); - } - - QList defectItems; - collect(count, arr, jobLayer, defectItems); - int sum = 0; - for (DefectViewCustom* item : defectItems) { - m_grdLt.addWidget(item, sum / m_colCount, sum % m_colCount); - sum++; - } - - m_grdScr.verticalScrollBar()->setSingleStep(m_grdScr.height()); - m_grdScr.verticalScrollBar()->setSliderPosition(0); - this->setFocus(); } -void PreVerifyWidget::collect(int count, QJsonArray& arr,QString& jobLayer, QList& defectItems) { - QPixmap px; - QPixmapCache::find(jobLayer, &px); - for (int i = 0; i < count; i++) { +void PreVerifyWidget::slot_treeWgtCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous) { + if (current == nullptr) { + return; + } + if (current->columnCount() == 1) { + switch (current->text(0).length()) { + case 7: + for (int i = 0; i < current->childCount(); i++) { + QTreeWidgetItem* dateItem = current->child(i); + loadDateItem(dateItem); + } + break; + case 10: + loadDateItem(current); + break; + default: + break; + } + } + else if (current->columnCount() > 1) { + if (m_boardDetail.boardId == current->text(1) + && m_boardDetail.jobLayer == current->text(0) + && m_boardDetail.date == current->parent()->text(0) + && m_boardDetail.hasCam == m_showCamChk.isChecked() + && m_boardDetail.showDefectCountCmbIndex == m_showDefectCountCmb.currentIndex()) { + return; + } + m_currentItem = current; + //取板信息 + m_boardDetail.showDefectCountCmbIndex = m_showDefectCountCmb.currentIndex(); + m_boardDetail.hasCam = m_showCamChk.isChecked(); + m_boardDetail.date = current->parent()->text(0); + m_boardDetail.jobLayer = current->text(0); + m_boardDetail.boardId = current->text(1); + m_boardDetail.side = current->text(2); + m_boardDetail.validSumCount = current->text(3); + m_boardDetail.validCount = m_boardDetail.validSumCount.split("/").at(0).toInt(); + m_boardDetail.sumCount = m_boardDetail.validSumCount.split("/").at(1).toInt(); + m_boardDetail.dir = AOI_DEFECT + "/" + m_boardDetail.date + "/" + m_boardDetail.boardId + "/"; + + //读参考图 + QString samplePath = "D:/PCBDataset/Reference/" + m_boardDetail.jobLayer + "/Learn/panel_image.png"; + if (!QPixmapCache::find(m_boardDetail.jobLayer, &m_samplePxmp)) { + m_samplePxmp.load(samplePath, nullptr, Qt::NoFormatConversion); + QPixmapCache::insert(m_boardDetail.jobLayer, m_samplePxmp); + } + + //读Json + QString fileName = m_boardDetail.dir + m_boardDetail.side + "I.vrs"; + if (QFile(fileName).exists()) { + JSONDocUtil::getInstance().readJSONDoc(fileName, m_vrsJson); + } + + //界面更新 + clear(); + m_curDefectLbl.setText(m_boardDetail.boardId + ":" + m_boardDetail.side + ":" + m_boardDetail.validSumCount); + int limit = std::min(m_limit, m_boardDetail.sumCount); + m_rowHeight = m_boardDetail.showDefectCountCmbIndex < 2 ? m_grdScr.height() - m_grdLt.spacing() : m_grdScr.height() / 2 - m_grdLt.spacing(); + getDefectImg(0, limit); + } +} + +void PreVerifyWidget::getDefectImg(int start,int end) { + QList defectItems; + QJsonArray arr = m_vrsJson.value("Defectx").toArray(); + + for (int i = start; i < end; i++) { int defectId = i + 1; - QString scanImgPath = m_dirPath + m_ab + QString::number(defectId) + ".jpg"; + QString scanImgPath = m_boardDetail.dir + m_boardDetail.side + QString::number(defectId) + ".jpg"; if (!QFile(scanImgPath).exists()) { continue; } @@ -453,16 +422,12 @@ void PreVerifyWidget::collect(int count, QJsonArray& arr,QString& jobLayer, QLis defectItem->m_preVerifyWgt = this; defectItem->setParent(this); QJsonObject obj = arr.at(i).toObject(); - bool isValid = true; - if (obj.contains("AIresult") && obj.value("AIresult") == 0) { - isValid = false; - } + bool isValid = (obj.contains("AIresult") && obj.value("AIresult") == 0) ? false : true; int defectType = obj.value("Code").toInt(); double x = obj.value("X").toDouble(); double y = obj.value("Y").toDouble(); - bool containSample = m_showCamChk.isChecked(); - defectItem->load(scanImgPath, defectId, isValid, x, y, jobLayer, px, defectType, m_rowHeight, containSample); + defectItem->load(scanImgPath, defectId, isValid, x, y, defectType, m_rowHeight, m_boardDetail); switch (m_colCount) { case 2: defectItem->scale(1.8, 1.8); @@ -481,6 +446,15 @@ void PreVerifyWidget::collect(int count, QJsonArray& arr,QString& jobLayer, QLis } defectItems.push_back(defectItem); } + int sum = start; + for (DefectViewCustom* item : defectItems) { + m_grdLt.addWidget(item, sum / m_colCount, sum % m_colCount); + sum++; + } + + m_grdScr.verticalScrollBar()->setSingleStep(m_grdScr.height()); + m_grdScr.verticalScrollBar()->setSliderPosition(0); + this->setFocus(); } //1.添加 -1.删除 @@ -501,7 +475,7 @@ void PreVerifyWidget::updateOne(QString defectId, int action) { m_vrsJson.insert("Defectx", arr); //写回 - QString vrsPath = m_dirPath + m_ab + "I.vrs"; + QString vrsPath = m_boardDetail.dir + m_boardDetail.side + "I.vrs"; JSONDocUtil::getInstance().writeJSONDoc(vrsPath, m_vrsJson); bool hasVerify = true; @@ -531,28 +505,19 @@ int PreVerifyWidget::getValid(QJsonObject& obj, bool& hasVerify){ return validSum; } -void PreVerifyWidget::filter() { +void PreVerifyWidget::filter(int index) { QString boardId = m_boardIdEdt.text(); QString job = m_jobEdt.text(); QString layer = m_layerEdt.text(); - //QString year = m_spinY.text(); - //QString month = m_spinM.text(); - //QString date = m_spinD.text(); QString year; QString month; QString date; - QString dd = m_dateCmb.currentText(); - if (!dd.isEmpty()) { - QStringList ll = dd.split("-"); + QString dateFull = m_dateCmb.currentText(); + if (!dateFull.isEmpty()) { + QStringList ll = dateFull.split("-"); year = ll.at(0); - month = ll.at(1); - date = ll.at(2); - } - if (month.size() == 1) { - month = "0" + month; - } - if (date.size() == 1) { - date = "0" + date; + month = ll.at(1).size() == 1 ? "0" + ll.at(1) : ll.at(1); + date = ll.at(2).size() == 1 ? "0" + ll.at(2) : ll.at(2); } int count = m_treeWgt.topLevelItemCount(); @@ -565,8 +530,9 @@ void PreVerifyWidget::filter() { yearItem->setHidden(false); int count2 = yearItem->childCount(); bool yearIsNull = true; + for (int j = 0; j < count2; j++) { - QTreeWidgetItem* monthItem = yearItem->child(j); + QTreeWidgetItem* monthItem = yearItem->child(j);//month if (!month.isEmpty() && !monthItem->text(0).endsWith(month)) { monthItem->setHidden(true); } @@ -574,16 +540,21 @@ void PreVerifyWidget::filter() { monthItem->setHidden(false); int count3 = monthItem->childCount(); bool monthIsNull = true; + for (int k = 0; k < count3; k++) { - QTreeWidgetItem* dateItem = monthItem->child(k); + QTreeWidgetItem* dateItem = monthItem->child(k);//date if (!date.isEmpty() && !dateItem->text(0).endsWith(date)) { dateItem->setHidden(true); } else { + if (!date.isEmpty() && dateItem->text(0).endsWith(date)) { + loadDateItem(dateItem);//先加载 + } dateItem->setHidden(false); bool dateIsNull = true; + for (int g = 0; g < dateItem->childCount(); g++) { - QTreeWidgetItem* boardItem = dateItem->child(g); + QTreeWidgetItem* boardItem = dateItem->child(g);//board if(!boardId.isEmpty()){ if (boardItem->text(1).contains(boardId)) { boardItem->setHidden(false); @@ -597,7 +568,7 @@ void PreVerifyWidget::filter() { boardItem->setHidden(false); } if (!job.isEmpty()) { - if (boardItem->text(0).contains(job)) { + if (boardItem->text(0).contains(job) && boardItem->text(0).split("/")[0].contains(job)) { boardItem->setHidden(false); } else { @@ -609,7 +580,7 @@ void PreVerifyWidget::filter() { boardItem->setHidden(false); } if (!layer.isEmpty()) { - if (boardItem->text(0).contains(layer)) { + if (boardItem->text(0).contains(layer) && boardItem->text(0).split("/")[1].contains(layer)) { boardItem->setHidden(false); } else { @@ -621,68 +592,85 @@ void PreVerifyWidget::filter() { boardItem->setHidden(false); } - if (!boardItem->isHidden()) { - dateIsNull = false; - monthIsNull = false; - yearIsNull = false; + if (!dateFull.isEmpty() && !boardItem->isHidden()) { + dateItem->setExpanded(true); + monthItem->setExpanded(true); + yearItem->setExpanded(true); + //dateIsNull = false; + //monthIsNull = false; + //yearIsNull = false; } } - if (dateIsNull) { - dateItem->setHidden(true); - } + //if (dateIsNull) { + // dateItem->setHidden(true); + //} } } - if (monthIsNull) { - monthItem->setHidden(true); - } + //if (monthIsNull) { + // monthItem->setHidden(true); + //} } } - if (yearIsNull) { - yearItem->setHidden(true); - } + //if (yearIsNull) { + // yearItem->setHidden(true); + //} } } - m_treeWgt.expandAll(); - m_treeWgt.setCurrentItem(nullptr); - clear(); + if (m_currentItem!=nullptr && m_currentItem->isHidden()) { + m_treeWgt.setCurrentItem(nullptr); + m_currentItem = nullptr; + m_boardDetail.clear(); + clear(); + } } void PreVerifyWidget::slot_lastBoardBtnPressed() { - QTreeWidgetItem* cur = m_treeWgt.currentItem(); + QTreeWidgetItem* cur = m_currentItem; if (cur == nullptr) { return; } - int ix = m_boardItemList.indexOf(cur); + int ix = m_boardItemList->indexOf(cur); while (ix - 1 >= 0) { - QTreeWidgetItem* lastItem = m_boardItemList.at(ix - 1); - if (!lastItem->isHidden() && !lastItem->parent()->isHidden() + QTreeWidgetItem* lastItem = m_boardItemList->at(ix - 1); + ix--; + if (lastItem->columnCount() == 1) { + continue; + } + if (!lastItem->isHidden() + && !lastItem->parent()->isHidden() && !lastItem->parent()->parent()->isHidden() - && !lastItem->parent()->parent()->parent()->isHidden()) { + && !lastItem->parent()->parent()->parent()->isHidden() + ) { m_treeWgt.setCurrentItem(lastItem); slot_treeWgtCurrentItemChanged(lastItem, cur); break; } - ix--; } } void PreVerifyWidget::slot_nextBoardBtnPressed() { - QTreeWidgetItem* cur = m_treeWgt.currentItem(); + QTreeWidgetItem* cur = m_currentItem; if (cur == nullptr) { return; } - int ix = m_boardItemList.indexOf(cur); - while (ix + 1 < m_boardItemList.size()) { - QTreeWidgetItem* nextItem = m_boardItemList.at(ix + 1); - if (!nextItem->isHidden() && !nextItem->parent()->isHidden() + + int ix = m_boardItemList->indexOf(cur); + while (ix + 1 < m_boardItemList->size()) { + QTreeWidgetItem* nextItem = m_boardItemList->at(ix + 1); + ix++; + if (nextItem->columnCount() == 1) { + continue; + } + if (!nextItem->isHidden() + && !nextItem->parent()->isHidden() && !nextItem->parent()->parent()->isHidden() - && !nextItem->parent()->parent()->parent()->isHidden()) { + && !nextItem->parent()->parent()->parent()->isHidden() + ) { m_treeWgt.setCurrentItem(nextItem); slot_treeWgtCurrentItemChanged(nextItem, cur); break; } - ix++; } } @@ -690,6 +678,7 @@ void PreVerifyWidget::slot_lastDefectBtnPressed() { if (m_treeWgt.currentItem() == nullptr) { return; } + QScrollBar* bar = m_grdScr.verticalScrollBar(); int sliderHeight = bar->singleStep(); int newPosition = bar->sliderPosition() - sliderHeight; @@ -718,6 +707,9 @@ void PreVerifyWidget::slot_nextDefectBtnPressed() { if (m_treeWgt.currentItem() == nullptr) { return; } + if (m_grdLt.count() < m_boardDetail.sumCount) { + getDefectImg(m_limit, m_boardDetail.sumCount); + } QScrollBar* bar = m_grdScr.verticalScrollBar(); int sliderHeight = bar->singleStep(); int newPosition = bar->sliderPosition() + sliderHeight; @@ -759,12 +751,4 @@ void PreVerifyWidget::keyPressEvent(QKeyEvent* event) { //QWidget::keyPressEvent(event); break; } -} - -void PreVerifyWidget::slot_winStateChangeEvent() { - slot_treeWgtCurrentItemChanged(m_treeWgt.currentItem(), nullptr); -} - -void PreVerifyWidget::slot_grdLtUpdate() { - update(); } \ No newline at end of file diff --git a/PreVerify/PreVerifyWidget.h b/PreVerify/PreVerifyWidget.h index c4cfcd9..ac59f7c 100644 --- a/PreVerify/PreVerifyWidget.h +++ b/PreVerify/PreVerifyWidget.h @@ -18,6 +18,30 @@ #include "qmutex.h" #include "logger.h" + +struct BoardDetail { + QString date; + QString jobLayer; + QString boardId; + QString side; + QString validSumCount; + int validCount; + int sumCount; + bool hasVerify = false; + bool hasCam = true; + QString dir; + int showDefectCountCmbIndex; + void clear() { + date.clear(); + jobLayer.clear(); + boardId.clear(); + side.clear(); + validSumCount.clear(); + validCount = 0; + sumCount = 0; + } +}; + class DefectViewCustom; class PreVerifyWidget : public QWidget { Q_OBJECT @@ -27,22 +51,24 @@ public: PreVerifyWidget(QWidget* parent = nullptr); void setUi(); void setConnection(); - void load(); - void collect(int count, QJsonArray& arr, QString& jobLayer, QList& defectItems); + void getDefectImg(int start, int end); void updateOne(QString defectId, int action); QString defectId2Desc(int defectId); - void filter(); + void filter(int index = 0); void showDefectCountCmbIndexChanged(); void keyPressEvent(QKeyEvent* event) override; - private: + const QString AOI_DEFECT = "D:/PCBDataset/Defect/fengming/AOI_DEFECT"; + const QString DEFECTTYPEDESCRIPTION_JSON = "D:/PCBDataset/GlobalSettings/defectTypeDescription.json"; void loadTreeWgt(); int getValid(QJsonObject& obj, bool& hasVerify); - void toJson(QJsonObject& yearJson, QString& path); + void getDateList(QJsonObject* yearJson); void readDefectTypesDesc(); void clear(); void loadDate(); + void getBoardList(QString date, QList* boardList); + void loadDateItem(QTreeWidgetItem* dateItem); QHBoxLayout m_lt; QGridLayout m_leftLt; @@ -53,27 +79,13 @@ private: QGridLayout m_grdLt; QLabel label1; - QLabel label11; QLabel label2; QLabel label3; QLabel label4; - QDateEdit m_dateEdt; - QPushButton m_yearClearBtn; - QPushButton m_monthClearBtn; - QPushButton m_dateClearBtn; + QComboBox m_dateCmb; QLineEdit m_boardIdEdt; QLineEdit m_jobEdt; QLineEdit m_layerEdt; - QLabel labelY; - QLabel labelM; - QLabel labelD; - QSpinBox m_spinY; - QSpinBox m_spinM; - QSpinBox m_spinD; - QHBoxLayout m_dateLt; - QComboBox m_dateCmb; - - QHBoxLayout m_pageBtnLt; QPushButton m_lastBoardBtn; @@ -85,20 +97,18 @@ private: QLabel m_showDefectCountLbl; QComboBox m_showDefectCountCmb; - - QString m_dirPath; QJsonObject m_vrsJson; QStringList m_removeList; - QString m_ab; QJsonObject m_defectTypesDescJson; QPixmap m_samplePxmp; int m_rowCount = 2; int m_colCount = 5; int m_rowHeight = -1; - QList m_boardItemList; + QList* m_boardItemList = nullptr; + BoardDetail m_boardDetail; + QTreeWidgetItem* m_currentItem = nullptr; + int m_limit = 120; -signals: - void sig_grdLtUpdate(); public slots: void slot_treeWgtCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous); @@ -106,8 +116,6 @@ public slots: void slot_lastDefectBtnPressed(); void slot_nextBoardBtnPressed(); void slot_nextDefectBtnPressed(); - void slot_winStateChangeEvent(); - void slot_grdLtUpdate(); }; diff --git a/PreVerify/main.cpp b/PreVerify/main.cpp index d45345f..0e2d8c4 100644 --- a/PreVerify/main.cpp +++ b/PreVerify/main.cpp @@ -18,9 +18,9 @@ LONG WINAPI exceptionCallback(struct _EXCEPTION_POINTERS* exceptionInfo); int main(int argc, char* argv[]) { QApplication a(argc, argv); - SetUnhandledExceptionFilter(exceptionCallback); + //SetUnhandledExceptionFilter(exceptionCallback); - QThreadPool::globalInstance()->setMaxThreadCount(15); + //QThreadPool::globalInstance()->setMaxThreadCount(15); MainWidget* mainWidget = new MainWidget(); diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..e69de29