diff --git a/include/global.h b/include/global.h index 3716a3f..34c6a27 100644 --- a/include/global.h +++ b/include/global.h @@ -8,7 +8,7 @@ #include #include #pragma execution_character_set("utf-8") -const std::string softwareVersion = "20251031-2.1.3"; +const std::string softwareVersion = "20251031-2.1.4"; const std::string euiJsonVersion = "1.0.6"; #define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 #define saveImgEnable 1 diff --git a/include/qtBridge.h b/include/qtBridge.h index f90ecd1..d5d4eaf 100644 --- a/include/qtBridge.h +++ b/include/qtBridge.h @@ -111,6 +111,7 @@ signals: void getCameraNames(std::vector* cameraNames); void getAllParams(std::vector>* params); void editParam(QString name, QVariant value); + void saveMissionJson(); private: explicit qtFuncBridge(QObject* parent = nullptr) : QObject(parent) {} ~qtFuncBridge() = default; diff --git a/include/sxGlobal.h b/include/sxGlobal.h index 470c3f8..35d99cf 100644 --- a/include/sxGlobal.h +++ b/include/sxGlobal.h @@ -138,6 +138,8 @@ public: camera->clearCache();//清除缓存 std::shared_ptr data = _serviceManager->_detDataManager->createDetData( QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包 + QString saveObjectName = ""; + data->saveObjectName = saveObjectName; camera->captureImage(data);//拍照 generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); diff --git a/include/yhGlobal.h b/include/yhGlobal.h index 555724b..d5ee313 100644 --- a/include/yhGlobal.h +++ b/include/yhGlobal.h @@ -171,6 +171,7 @@ public: camera->clearCache(); std::shared_ptr data = _serviceManager->_detDataManager->createDetData( QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包 + data->saveObjectName = saveObjectName; camera->captureImage(data);//拍照 generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); @@ -253,6 +254,7 @@ public: camera->clearCache(); std::shared_ptr data = _serviceManager->_detDataManager->createDetData( QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包 + data->saveObjectName = saveObjectName; camera->captureImage(data);//拍照 generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index 634f16b..a0937a0 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -235,24 +235,24 @@ public: std::shared_ptr resJob(new saveJob("[RES_JOB]" + data->SNcode)); QString oriSavePath = _ImageSavePathFormatter.genPath(data, oriImg, data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 - if (saveOri == true || saveSeg == true || saveCls == true) + if (saveOri == true || saveSeg == true || saveCls == true) { createDirectoryIfNotExists(oriSavePath);//不存在此文件夹则创建 - else { - if (data->oriImgs.size() != 0 && saveOri != false) { + if (data->oriImgs.size() != 0 && saveOri == true) { std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, oriImg, data->oriImgs);//按规则为文件创建命名 packageData(oriJob->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->oriImgs);//打包数据 } //SEG原图 - if (data->segOriginImgs.size() != 0 && saveSeg != false) { + if (data->segOriginImgs.size() != 0 && saveSeg == true) { std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, segImg, data->segOriginImgs);//按规则为文件创建命名 packageData(resJob->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->segOriginImgs);//打包数据 } //CLS原图 - if (data->clsOriginImgs.size() != 0 && saveCls != false) { + if (data->clsOriginImgs.size() != 0 && saveCls == true) { std::vectorfileNames = _ImageSavePathFormatter.genClsFileNames(data, clsImg, data->clsOriginImgs);//按规则为文件创建命名 packageData(resJob->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->clsOriginImgs);//打包数据 } } + QString resSavePath = _ImageSavePathFormatter.genPath(data, resImg, data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 if (saveRes == true){ diff --git a/src/launcher/GUI/paramEditorDialog.h b/src/launcher/GUI/paramEditorDialog.h index 27edfb4..2e11d00 100644 --- a/src/launcher/GUI/paramEditorDialog.h +++ b/src/launcher/GUI/paramEditorDialog.h @@ -225,6 +225,7 @@ private slots: //result.push_back({ key, convertedValue }); emit qtFuncBridge::getInstance()->editParam(key, convertedValue); } + emit qtFuncBridge::getInstance()->saveMissionJson(); this->close(); delete this; //qDebug() << "Result JSON: " << QString::fromStdString(result.dump(4)); diff --git a/src/launcher/GUI/uiModule/uiModule_imageView.h b/src/launcher/GUI/uiModule/uiModule_imageView.h index 798d3fd..d33cf4b 100644 --- a/src/launcher/GUI/uiModule/uiModule_imageView.h +++ b/src/launcher/GUI/uiModule/uiModule_imageView.h @@ -97,6 +97,9 @@ public: setInteractive(false); setEnabled(false); setObjectName("SonGraphicsView"); + // 缩放以视图中心为锚点 + setTransformationAnchor(QGraphicsView::AnchorViewCenter); + setResizeAnchor(QGraphicsView::AnchorViewCenter); //scene->addItem(rectGroup); setScene(scene); @@ -138,12 +141,20 @@ protected: if (scene->items().isEmpty()) return; - QPoint numDegrees = event->angleDelta() / 8; - if (!numDegrees.isNull()) { - zoom(numDegrees / 15); - centerOn(currentPos); + // 支持高分辨率触控板与普通滚轮,按步进平滑缩放 + const QPoint angle = event->angleDelta(); + double steps = 0.0; + if (!angle.isNull()) { + steps = static_cast(angle.y()) / 120.0; // 120 == one step } - event->accept(); + if (steps != 0.0) { + // 以图像中心为缩放中心 + centerOnImageCenter(); + zoom(steps); + event->accept(); + return; + } + QGraphicsView::wheelEvent(event); } void keyPressEvent(QKeyEvent* event) override { @@ -233,6 +244,30 @@ private: QMutex mutex; + // 计算当前视图适配整图时的缩放倍率 + double fitScale() const { + if (!pixmapItem) return 1.0; + QRectF br = pixmapItem->boundingRect(); + if (br.isEmpty()) return 1.0; + QSize vp = viewport()->size(); + if (vp.width() <= 0 || vp.height() <= 0) return 1.0; + double sx = static_cast(vp.width()) / br.width(); + double sy = static_cast(vp.height()) / br.height(); + return std::min(sx, sy); + } + + // 根据当前内容更新缩放上下限 + void updateZoomBounds() { + double f = fitScale(); + minScaleBound = std::max(f * 0.2, 1e-3); // 最小可视缩放(不至于太小) + maxScaleBound = std::max(minScaleBound * 500.0, f * 50.0); // 最大放大倍数 + } + + // 获取当前统一缩放(假设等比缩放) + double currentScale() const { + return transform().m11(); + } + void showImg(const QPixmap& img) { QMutexLocker locker(&mutex); setEnabled(true); @@ -251,19 +286,40 @@ private: scene->addItem(pixmapItem); setSceneRect(img.rect()); + // 重置变换并自适应居中显示 + resetTransform(); fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio); + updateZoomBounds(); } + // 旧接口保留,转调到新的双精度缩放 void zoom(const QPoint& factor) { - QRectF FOV = mapToScene(rect()).boundingRect(); - float scaleX = static_cast(imageWidth) / FOV.width(); - float scaleY = static_cast(imageHeight) / FOV.height(); + zoom(static_cast(factor.y())); + } - double currentScale = transform().m11(); - if ((factor.y() > 0 && currentScale > 10.0) || (factor.y() < 0 && currentScale < 1)) - return; + // 新的缩放实现:按步进平滑缩放,并限制上下限 + void zoom(double steps) { + if (steps == 0.0 || !pixmapItem) return; + // 每个滚轮档位使用指数缩放,数值可根据体验调整 + const double perStep = 1.15; // 单步缩放系数 + double desiredFactor = std::pow(perStep, steps); - scale(factor.y() > 0 ? 1.1 : 0.9, factor.y() > 0 ? 1.1 : 0.9); + double cur = currentScale(); + // 目标缩放值(绝对) + double target = cur * desiredFactor; + // 边界更新并裁剪 + updateZoomBounds(); + if (target < minScaleBound) target = minScaleBound; + if (target > maxScaleBound) target = maxScaleBound; + // 需要应用的相对缩放 + double apply = target / cur; + if (std::abs(apply - 1.0) < 1e-6) return; + scale(apply, apply); + } + + void centerOnImageCenter() { + if (!pixmapItem) return; + centerOn(pixmapItem); } void togglePan(bool pan, const QPoint& startPos = QPoint()) { @@ -296,6 +352,10 @@ private: } }*/ } + + // 缩放界限(根据内容动态调整) + double minScaleBound = 1e-3; + double maxScaleBound = 1e6; }; //切换窗口 在切换时用pixmap替换现有的以实现 class ImageWidget : public QWidget { @@ -386,7 +446,8 @@ public: layout->addWidget(viewer); viewer->setDragMode(QGraphicsView::ScrollHandDrag); - viewer->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + // 以视图中心为缩放锚点 + viewer->setTransformationAnchor(QGraphicsView::AnchorViewCenter); viewer->setRenderHint(QPainter::Antialiasing); viewer->setRenderHint(QPainter::SmoothPixmapTransform); viewer->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 15d3d07..5dd59cf 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -180,6 +180,12 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* _core->_backEnd.backend, &IBackend::getAllParams, Qt::DirectConnection); QObject::connect(bridge, &qtFuncBridge::editParam, _core->_backEnd.backend, &IBackend::editParam, Qt::DirectConnection); + QObject::connect(bridge, &qtFuncBridge::saveMissionJson, + _core->_backEnd.backend, [=]() { + auto &config = appConfig::getInstance(); + config.missionJson["backend"] = _core->_backEnd.backend->getJson(); + config.saveSettingJson(); + }, Qt::DirectConnection); } int main(int argc, char* argv[]) diff --git a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h index 0e38554..5572442 100644 --- a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h +++ b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h @@ -79,7 +79,7 @@ static bool ManHan(std::shared_ptr data, mfd_detParams* _detParams, yh cameraNumberStr = "4"; FixtureNumber = "8"; } - data->customPath = QString::fromStdString("{imgSaveRootDir}/{yyyy-MM-dd}/{HH}H/{imageType}/{processResult}/相机" + cameraNumberStr + "孔" + FixtureNumber + "/"); + data->customPath = QString::fromStdString("{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{HH}H/{processResult}/相机" + cameraNumberStr + "孔" + FixtureNumber + "/"); HalconCpp::HObject in_Image = MatToHObject(src1); HDevEngineCpp::HDevProcedure proc("_9_manhan"); HDevProcedureCall procedureCall(proc);