This commit is contained in:
2025-10-28 17:29:39 +08:00
parent 4fe5cff926
commit 2a66d1d1f2
12 changed files with 113 additions and 36 deletions
+77
View File
@@ -12,6 +12,83 @@
#include <QFileInfo>
#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;
+1 -1
View File
@@ -70,7 +70,7 @@ static bool generalAlgoTest(std::shared_ptr <detData> 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;
}
+1 -1
View File
@@ -88,7 +88,7 @@ static bool generalAlgoTest(std::shared_ptr <detData> 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;
}
+10 -9
View File
@@ -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<std::pair<std::string, std::string>> sqlVec;
#pragma region 基础函数
static QString getUuid() {
return QUuid::createUuid().toString();
@@ -60,7 +53,15 @@ public:
QString customPath = "",customFileName = "";
std::vector<std::pair <QString, QString>>customImageSaveTemplateParams;
#pragma endregion
QMap<QString, QVariant> additional;
#pragma region 结果相关
bool aiDetOK = true;
bool halconOK = true;
//结果图展示预设
std::vector< showImgPack>resultImgShowSet;
//需要存入的SQL数据
std::vector<std::pair<std::string, std::string>> sqlVec;
#pragma endregion
QMap<QString, QVariant> additional;//自定义参数
detData() {}
~detData() {
for (auto& img : oriImgs)
+4 -1
View File
@@ -7,7 +7,7 @@ public:
qtBridge = qtBridgeIn;
}
//如果需要根据条码判断一个料的okng,只需要调用此函数即可
void handleAllResult(std::string SN,bool isNG,std::vector<std::string> defectAndNum) {
void toBarChart(std::string SN,bool isNG,std::vector<std::string> 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);
+1
View File
@@ -358,6 +358,7 @@ public:
//SUB
void registerPlcValueViewer(const QString& groupName, const std::vector<PlcValueViewerStruct>& viewerDatas) {
QMutexLocker locer(&mutex);
for (auto& data : viewerDatas) {
if (data.valueAddr < 0)continue;
plcValueViewerDatas.push_back(data);
+3 -4
View File
@@ -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);
}
+8 -1
View File
@@ -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();
+1 -12
View File
@@ -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);
+1 -1
View File
@@ -53,7 +53,7 @@ public:
// void resultHandle(std::shared_ptr <detData>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:
+5 -5
View File
@@ -131,7 +131,7 @@ static bool BaoMoHou_ShangDaMian(std::shared_ptr <detData> 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 <detData> data, baoMoHouDaMianD
// void resultHandle(std::shared_ptr <detData>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 <detData> data, baoMoHouDaMianDet
// void resultHandle(std::shared_ptr <detData>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 <detData> 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 <detData> 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);
+1 -1
View File
@@ -113,7 +113,7 @@ bool ALGO_BaoMoHouCeMian(std::shared_ptr <detData> 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;