From 2a66d1d1f2e68b416ffca4205cfd7fd4916cc301 Mon Sep 17 00:00:00 2001 From: RCi <15089880081@163.com> Date: Tue, 28 Oct 2025 17:29:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/simpleTools/windowsCtrl.hpp | 77 ++++++++++++++++++++ include/sxGlobal.h | 2 +- include/yhGlobal.h | 2 +- src/core/service/detData.h | 19 ++--- src/core/service/missionResultHandle.h | 5 +- src/core/service/triggerManager.h | 1 + src/launcher/GUI/front/pages/logPageWidget.h | 7 +- src/launcher/GUI/mainwindow.h | 9 ++- src/launcher/main.cpp | 13 +--- src/mission/581-BaoMo-Cam1234/581-BaoMo.h | 2 +- src/mission/581-BaoMo-Cam5678/581-BaoMo.h | 10 +-- src/mission/581-BaoMo-Cam91011/581-BaoMo.cpp | 2 +- 12 files changed, 113 insertions(+), 36 deletions(-) diff --git a/include/simpleTools/windowsCtrl.hpp b/include/simpleTools/windowsCtrl.hpp index 4afa251..b3c40fc 100644 --- a/include/simpleTools/windowsCtrl.hpp +++ b/include/simpleTools/windowsCtrl.hpp @@ -12,6 +12,83 @@ #include #pragma comment(lib, "setupapi.lib") +// 禁用控制台选择(快速编辑与鼠标输入) +static bool disableConsoleSelection() { + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + if (hStdin == INVALID_HANDLE_VALUE || hStdin == NULL) return false; + + DWORD mode = 0; + if (!GetConsoleMode(hStdin, &mode)) return false; + + // 必须先设置 ENABLE_EXTENDED_FLAGS,再清除 ENABLE_QUICK_EDIT_MODE + DWORD newMode = mode | ENABLE_EXTENDED_FLAGS; + newMode &= ~(ENABLE_QUICK_EDIT_MODE | ENABLE_MOUSE_INPUT); + + if (newMode == mode) return true; // 已经是期望模式 + return SetConsoleMode(hStdin, newMode) != 0; +} + +// 恢复控制台选择(快速编辑与鼠标输入) +static bool enableConsoleSelection() { + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + if (hStdin == INVALID_HANDLE_VALUE || hStdin == NULL) return false; + + DWORD mode = 0; + if (!GetConsoleMode(hStdin, &mode)) return false; + + DWORD newMode = mode | ENABLE_EXTENDED_FLAGS | ENABLE_QUICK_EDIT_MODE | ENABLE_MOUSE_INPUT; + if (newMode == mode) return true; + return SetConsoleMode(hStdin, newMode) != 0; +} + +// 是否运行在 Windows Terminal 主机(PowerShell/命令行在 Windows Terminal 中) +static bool isWindowsTerminalHost() { + // Windows Terminal 会设置 WT_SESSION 环境变量 + return GetEnvironmentVariableW(L"WT_SESSION", nullptr, 0) > 0; +} + +// 绑定 CRT 与标准句柄到当前控制台 +static void bindCrtToConsoleIO() { + FILE* fp = nullptr; + freopen_s(&fp, "CONIN$", "r", stdin); + freopen_s(&fp, "CONOUT$", "w", stdout); + freopen_s(&fp, "CONOUT$", "w", stderr); + // 同步 C++ iostream 与 C stdio + std::ios::sync_with_stdio(); +} + +// 确保获得一个“不可选择”的控制台。 +// 如果检测到 Windows Terminal/PowerShell 环境,则脱离父控制台并新建独立控制台,避免被宿主选择影响。 +static bool ensureNoSelectionConsole(bool detachWhenWT = true) { + bool createdNew = false; + + if (detachWhenWT && isWindowsTerminalHost()) { + FreeConsole(); // 脱离 PowerShell/WT 的控制台 + if (AllocConsole()) { + bindCrtToConsoleIO(); + createdNew = true; + } + } else if (GetConsoleWindow() == NULL) { + // GUI 子系统或当前无控制台时创建一个 + if (AllocConsole()) { + bindCrtToConsoleIO(); + createdNew = true; + } + } else { + // 已有控制台,仍然尝试绑定,避免句柄无效 + bindCrtToConsoleIO(); + } + + // 禁用选择(对当前控制台生效) + bool ok = disableConsoleSelection(); + + // 保险:确保控制台窗口可见 + if (HWND hWnd = GetConsoleWindow()) { + ShowWindow(hWnd, SW_SHOW); + } + return createdNew ? ok : ok; +} + static void DisableComPort(const char* portName) { HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; diff --git a/include/sxGlobal.h b/include/sxGlobal.h index da5a7ca..470c3f8 100644 --- a/include/sxGlobal.h +++ b/include/sxGlobal.h @@ -70,7 +70,7 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam textPainter.putText(Paint, "划伤", cv::Point(10,10), cv::Scalar(0, 255, 0)); cv::putText(Paint, "pos:" + data->additional["触发地址"].toString().toStdString(), cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 2); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - data->service->_missionResultHandle->handleAllResult(data->SNcode, !defects.size() > 0, defects);//发送图标操作 + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects);//发送图标操作 data->resultImgs.push_back(Paint); return true; } diff --git a/include/yhGlobal.h b/include/yhGlobal.h index f1c1d89..555724b 100644 --- a/include/yhGlobal.h +++ b/include/yhGlobal.h @@ -88,7 +88,7 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.123");//发送数据1 data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2)+ "_0.456");//发送数据2 data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - data->service->_missionResultHandle->handleAllResult(data->SNcode, !defects.size() > 0, defects);//发送图标操作 + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects);//发送图标操作 data->resultImgs.push_back(Paint); return true; } diff --git a/src/core/service/detData.h b/src/core/service/detData.h index a27d5da..df755cc 100644 --- a/src/core/service/detData.h +++ b/src/core/service/detData.h @@ -24,14 +24,7 @@ public: std::chrono::steady_clock::time_point getImageTime; long long algoTime = 0;//算法执行时间容器 //参数 - - //结果 - bool aiDetOK = true; - bool halconOK = true; - //结果图展示预设 - std::vector< showImgPack>resultImgShowSet; - //需要存入的SQL数据 - std::vector> sqlVec; + #pragma region 基础函数 static QString getUuid() { return QUuid::createUuid().toString(); @@ -60,7 +53,15 @@ public: QString customPath = "",customFileName = ""; std::vector>customImageSaveTemplateParams; #pragma endregion - QMap additional; +#pragma region 结果相关 + bool aiDetOK = true; + bool halconOK = true; + //结果图展示预设 + std::vector< showImgPack>resultImgShowSet; + //需要存入的SQL数据 + std::vector> sqlVec; +#pragma endregion + QMap additional;//自定义参数 detData() {} ~detData() { for (auto& img : oriImgs) diff --git a/src/core/service/missionResultHandle.h b/src/core/service/missionResultHandle.h index 78cde9e..7125f75 100644 --- a/src/core/service/missionResultHandle.h +++ b/src/core/service/missionResultHandle.h @@ -7,7 +7,7 @@ public: qtBridge = qtBridgeIn; } //如果需要根据条码判断一个料的okng,只需要调用此函数即可 - void handleAllResult(std::string SN,bool isNG,std::vector defectAndNum) { + void toBarChart(std::string SN,bool isNG,std::vector defectAndNum) { if (isNG == false) { qtBridge->pieWidgetAddOK(); } @@ -15,6 +15,9 @@ public: emit qtBridge->pieWidgetAddNG(); } emit qtBridge->histogramWidgetAddData(defectAndNum); + } + void toWaveForm() { + } void test() { QThread::msleep(1000); diff --git a/src/core/service/triggerManager.h b/src/core/service/triggerManager.h index c79f697..0f729e9 100644 --- a/src/core/service/triggerManager.h +++ b/src/core/service/triggerManager.h @@ -358,6 +358,7 @@ public: //SUB void registerPlcValueViewer(const QString& groupName, const std::vector& viewerDatas) { + QMutexLocker locer(&mutex); for (auto& data : viewerDatas) { if (data.valueAddr < 0)continue; plcValueViewerDatas.push_back(data); diff --git a/src/launcher/GUI/front/pages/logPageWidget.h b/src/launcher/GUI/front/pages/logPageWidget.h index bfdd017..5ef65c2 100644 --- a/src/launcher/GUI/front/pages/logPageWidget.h +++ b/src/launcher/GUI/front/pages/logPageWidget.h @@ -190,10 +190,9 @@ public: filterStates[index].autoScroll = checked; }); - connect(openDirBtn, &QPushButton::clicked, - [=]() { - QDesktopServices::openUrl(QUrl::fromLocalFile("./Log")); - }); + connect(openDirBtn, &QPushButton::clicked,[=]() { + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(logBasePath))); + }); widgetLayout->addWidget(textWidget); } diff --git a/src/launcher/GUI/mainwindow.h b/src/launcher/GUI/mainwindow.h index 2e13900..d15fa47 100644 --- a/src/launcher/GUI/mainwindow.h +++ b/src/launcher/GUI/mainwindow.h @@ -406,8 +406,15 @@ public slots: _loadingWidget.clearLog(); backEndInit = true; logService::getInstance()->disableLoadingWidgetOutput(); - if (isLogin == true) + if (isLogin == true) { loading(false); + } + #if HIDE_CONSOLE + logService::getInstance()->disableConsoleOutput(); + if (config->consoleHandle) { + ShowWindow(config->consoleHandle, SW_HIDE); + }// 隐藏控制台窗口 + #endif break; default: _loadingWidget.setError(); diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 13a5d76..4b73949 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -177,13 +177,8 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* int main(int argc, char* argv[]) { - //if (!isRunAsAdmin()) - //{ - // restartAsAdmin(); - // exit(0); - //} - #pragma region 设置显示控制栏 + disableConsoleSelection(); HWND hWnd = GetConsoleWindow(); ShowWindow(hWnd, SW_SHOW); #pragma endregion @@ -233,12 +228,6 @@ int main(int argc, char* argv[]) // 创建后端对象 _core._backEnd.loadCore(config.dataBase,bridge, config.missionJson["backend"]); // 加载核心功能 connectSignalAndSlot(&_core, &w, bridge); // 连接信号和槽 -#if HIDE_CONSOLE - if (config.consoleHandle) { - ShowWindow(config.consoleHandle, SW_HIDE); - _core._logService->disableConsoleOutput(); - }// 隐藏控制台窗口 -#endif w.registerQuitFunc([&]() { _core._backEnd.releaseCore(); // 释放核心功能 QThread::msleep(100); diff --git a/src/mission/581-BaoMo-Cam1234/581-BaoMo.h b/src/mission/581-BaoMo-Cam1234/581-BaoMo.h index 342bd28..0a9ba18 100644 --- a/src/mission/581-BaoMo-Cam1234/581-BaoMo.h +++ b/src/mission/581-BaoMo-Cam1234/581-BaoMo.h @@ -53,7 +53,7 @@ public: // void resultHandle(std::shared_ptr data, _581_Result resultData) { // _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 // _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// _serviceManager->_missionResultHandle->handleAllResult(data->SNcode, resultData.result, resultData.defects); +// _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); // // } //private: diff --git a/src/mission/581-BaoMo-Cam5678/581-BaoMo.h b/src/mission/581-BaoMo-Cam5678/581-BaoMo.h index b5fe8a3..7665f0d 100644 --- a/src/mission/581-BaoMo-Cam5678/581-BaoMo.h +++ b/src/mission/581-BaoMo-Cam5678/581-BaoMo.h @@ -131,7 +131,7 @@ static bool BaoMoHou_ShangDaMian(std::shared_ptr data, baoMoHouDaMianD } data->resultImgs.push_back(Paint); - data->service->_missionResultHandle->handleAllResult(data->SNcode, defects.size() == 0, defects); + data->service->_missionResultHandle->toBarChart(data->SNcode, defects.size() == 0, defects); data->service->_triggerManager->writeFloat("D" + address.resultAddr + "_1");//发送OK return true; } @@ -177,7 +177,7 @@ static bool BaoMoHou_ShangDaMian(std::shared_ptr data, baoMoHouDaMianD // void resultHandle(std::shared_ptr data, _581_BaoMoResult resultData) { // _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 // _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// _serviceManager->_missionResultHandle->handleAllResult(data->SNcode, resultData.result, resultData.defects); +// _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); // // } //private: @@ -297,7 +297,7 @@ static bool BaoMoHou_XiaDaMian(std::shared_ptr data, baoMoHouDaMianDet // void resultHandle(std::shared_ptr data, _581_BaoMoResult resultData) { // _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 // _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// _serviceManager->_missionResultHandle->handleAllResult(data->SNcode, resultData.result, resultData.defects); +// _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); // // } //private: @@ -329,7 +329,7 @@ public: //baoMoHouShangDaMianTrigger::resultHandleCallback resultCallback_BaoMoHouShangDaMian = // ([=](yh_581_address address, _581_BaoMoResult resultData, std::shared_ptr data ) { // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // _serviceManager->_missionResultHandle->handleAllResult(data->SNcode, resultData.result, resultData.defects); + // _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); // }); _station_1.init("Camera1", "包膜后大面外观检测相机5(上大面1)",18800,2,1, &_baoMoHouDaMianDetParams, _serviceManager,bridge, BaoMoHou_ShangDaMian); _station_3.init("Camera3", "包膜后大面外观检测相机7(上大面2)", 19200, 2, 1, &_baoMoHouDaMianDetParams, _serviceManager, bridge, BaoMoHou_ShangDaMian); @@ -337,7 +337,7 @@ public: //baoMoHouXiaDaMianTrigger::resultHandleCallback resultCallback_BaoMoHouXiaDaMian = // ([=](yh_581_address address, _581_BaoMoResult resultData, std::shared_ptr data) { // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // _serviceManager->_missionResultHandle->handleAllResult(data->SNcode, resultData.result, resultData.defects); + // _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); // }); _station_2.init("Camera2", "包膜后大面外观检测相机6(下大面四角1)", 19000, 2, 1, &_baoMoHouDaMianDetParams, _serviceManager, bridge, BaoMoHou_XiaDaMian); _station_4.init("Camera4", "包膜后大面外观检测相机8(下大面四角2)",19400,2,1, &_baoMoHouDaMianDetParams, _serviceManager, bridge, BaoMoHou_XiaDaMian); diff --git a/src/mission/581-BaoMo-Cam91011/581-BaoMo.cpp b/src/mission/581-BaoMo-Cam91011/581-BaoMo.cpp index 6953511..6d208e8 100644 --- a/src/mission/581-BaoMo-Cam91011/581-BaoMo.cpp +++ b/src/mission/581-BaoMo-Cam91011/581-BaoMo.cpp @@ -113,7 +113,7 @@ bool ALGO_BaoMoHouCeMian(std::shared_ptr data, baoMoHouDaMianDetParams defects.push_back("算法不良"); } data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - data->service->_missionResultHandle->handleAllResult(data->SNcode, !defects.size()>0, defects); + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size()>0, defects); data->resultImgs.push_back(Paint); return true;