diff --git a/configSettingWidget.h b/configSettingWidget.h index abecfe3..c8826e8 100644 --- a/configSettingWidget.h +++ b/configSettingWidget.h @@ -19,7 +19,6 @@ #include #include #include -#include #include "git_version.h" #include #include @@ -386,7 +385,7 @@ protected: private: appConfig* _config; - hardwareInfoWidget _hardwareInfoWidget; + //hardwareInfoWidget _hardwareInfoWidget; //std::vector> privateJsondatas;//路径与数据 //std::vector> privateWidgets;//路径与数据 //std::vectorjsonLayouts; diff --git a/include/global.h b/include/global.h index 561c97d..2c617ce 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 = "V20251030-2.1.1"; +const std::string softwareVersion = "V20251031-2.1.2"; const std::string euiJsonVersion = "1.0.6"; #define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 #define saveImgEnable 1 diff --git a/include/simpleAlgo.h b/include/simpleAlgo.h index 4c5f090..dd29758 100644 --- a/include/simpleAlgo.h +++ b/include/simpleAlgo.h @@ -74,8 +74,42 @@ static cv::Rect findMaxAreaContour(cv::Mat src, int& indexReturn) return cv::boundingRect(contours[maxIndex]); } } -static cv::Mat cutImg2Cls(cv::Rect boundingBox, cv::Mat imgInput, cv::Size targetSize = cv::Size(128, 128)); -static cv::Mat cutImg2Cls(std::vector contour, cv::Mat imgInput, cv::Size targetSize = cv::Size(128, 128)); + +static cv::Mat cutImg2Cls(cv::Rect boundingBox, cv::Mat imgInput, cv::Size targetSize = cv::Size(128, 128)) +{ + if (boundingBox.width <= 0 || boundingBox.height <= 0 || imgInput.empty()) { + std::cerr << "Invalid bounding box or empty input image." << std::endl; + return cv::Mat(); + } + + // 以目标框中心为正方形中心,边长为 max(max(w,h),128) + const cv::Point mid(boundingBox.x + boundingBox.width / 2, boundingBox.y + boundingBox.height / 2); + const int sideLength = getMax(getMax(boundingBox.width, boundingBox.height), 128); + + // 期望在原图上的 ROI(可能越界) + cv::Rect expectRect(mid.x - sideLength / 2, mid.y - sideLength / 2, sideLength, sideLength); + + // 计算需要的边界填充(反射填充) + const int left = getMax(0, -expectRect.x); + const int top = getMax(0, -expectRect.y); + const int right = getMax(0, expectRect.x + expectRect.width - imgInput.cols); + const int bottom = getMax(0, expectRect.y + expectRect.height - imgInput.rows); + + cv::Mat padded; + if (left || top || right || bottom) { + cv::copyMakeBorder(imgInput, padded, top, bottom, left, right, cv::BORDER_REFLECT_101); + } else { + padded = imgInput; + } + + // 在填充后图像上的 ROI(保证不越界) + cv::Rect shifted(expectRect.x + left, expectRect.y + top, expectRect.width, expectRect.height); + + // 最终裁剪并缩放 + cv::Mat squareImage = padded(shifted).clone(); + cv::resize(squareImage, squareImage, targetSize); + return squareImage; +} static std::vector cutImg2ClsVec(cv::Rect boundingBox, cv::Mat imgInput, cv::Size targetSize = cv::Size(128, 128)) { @@ -86,97 +120,47 @@ static std::vector cutImg2ClsVec(cv::Rect boundingBox, cv::Mat imgInput return result; } - int minSide = getMin(boundingBox.width, boundingBox.height); - if (minSide == 0) { + const int w = boundingBox.width; + const int h = boundingBox.height; + const int minSide = getMin(w, h); + if (minSide <= 0) { std::cerr << "Bounding box has zero width or height." << std::endl; return result; } - int splitCount = getMax(1, getMax(boundingBox.width, boundingBox.height) / minSide); + // 沿长边切分为若干个 size=minSide 的方块,覆盖到末端且避免重复最后一块 + const bool splitHoriz = (w > h); // 横向长 -> 沿X方向切 + const int longSide = splitHoriz ? w : h; + const int step = minSide; + const int beginCoord = splitHoriz ? boundingBox.x : boundingBox.y; + const int endCoord = beginCoord + longSide; - if (splitCount > 2) { - if (boundingBox.width > boundingBox.height) { // 横向裁 - for (int i = 0; i < splitCount; i++) { - int x = boundingBox.x + boundingBox.height * i; - if (x + boundingBox.height > boundingBox.x + boundingBox.width) - break; - result.emplace_back(cutImg2Cls(cv::Rect(x, boundingBox.y, boundingBox.height, boundingBox.height), imgInput, targetSize)); - } - // 确保最右边包含 - result.emplace_back(cutImg2Cls(cv::Rect(boundingBox.x + boundingBox.width - boundingBox.height, boundingBox.y, boundingBox.height, boundingBox.height), imgInput, targetSize)); - } - else { // 纵向裁 - for (int i = 0; i < splitCount; i++) { - int y = boundingBox.y + boundingBox.width * i; - if (y + boundingBox.width > boundingBox.y + boundingBox.height) - break; - result.emplace_back(cutImg2Cls(cv::Rect(boundingBox.x, y, boundingBox.width, boundingBox.width), imgInput, targetSize)); - } - result.emplace_back(cutImg2Cls(cv::Rect(boundingBox.x, boundingBox.y + boundingBox.height - boundingBox.width, boundingBox.width, boundingBox.width), imgInput, targetSize)); - } + // 计算切块起点列表 + std::vector starts; + starts.reserve((longSide + step - 1) / step); + for (int s = beginCoord; s + step <= endCoord; s += step) { + starts.emplace_back(s); } - else { - result.emplace_back(cutImg2Cls(boundingBox, imgInput, targetSize)); + // 确保包含末端(避免遗漏),同时避免与最后一个重复 + const int lastStart = endCoord - step; + if (starts.empty() || starts.back() != lastStart) { + starts.emplace_back(lastStart); + } + + result.reserve(starts.size()); + if (splitHoriz) { + for (int x : starts) { + result.emplace_back(cutImg2Cls(cv::Rect(x, boundingBox.y, minSide, minSide), imgInput, targetSize)); + } + } else { + for (int y : starts) { + result.emplace_back(cutImg2Cls(cv::Rect(boundingBox.x, y, minSide, minSide), imgInput, targetSize)); + } } return result; } -static cv::Mat cutImg2Cls(std::vector contour, cv::Mat imgInput, cv::Size targetSize) -{ - if (contour.empty() || imgInput.empty()) { - std::cerr << "Empty contour or input image." << std::endl; - return cv::Mat(); - } - - cv::Rect boundingBox = cv::boundingRect(contour); - return cutImg2Cls(boundingBox, imgInput, targetSize); -} - -static cv::Mat cutImg2Cls(cv::Rect boundingBox, cv::Mat imgInput, cv::Size targetSize) -{ - if (boundingBox.width <= 0 || boundingBox.height <= 0 || imgInput.empty()) { - std::cerr << "Invalid bounding box or empty input image." << std::endl; - return cv::Mat(); - } - - cv::Point mid(boundingBox.x + boundingBox.width / 2, boundingBox.y + boundingBox.height / 2); - int sideLength = getMax(getMax(boundingBox.width, boundingBox.height), 128); - - // 生成一个空的正方形黑图 - cv::Mat squareImage(sideLength, sideLength, imgInput.type(), cv::Scalar(0, 0, 0)); - - // 从原图中取的期望矩形区域 - cv::Rect expectRect(mid.x - sideLength / 2, mid.y - sideLength / 2, sideLength, sideLength); - - int xOffset = 0; - int yOffset = 0; - - // 调整 expectRect 防止越界 - if (expectRect.x < 0) { - expectRect.width += expectRect.x; - xOffset -= expectRect.x; - expectRect.x = 0; - } - if (expectRect.y < 0) { - expectRect.height += expectRect.y; - yOffset -= expectRect.y; - expectRect.y = 0; - } - if (expectRect.x + expectRect.width > imgInput.cols) - expectRect.width = imgInput.cols - expectRect.x; - if (expectRect.y + expectRect.height > imgInput.rows) - expectRect.height = imgInput.rows - expectRect.y; - - if (expectRect.width <= 0 || expectRect.height <= 0) { - std::cerr << "Adjusted region is invalid after clipping." << std::endl; - return cv::Mat(); - } - - imgInput(expectRect).copyTo(squareImage(cv::Rect(xOffset, yOffset, expectRect.width, expectRect.height))); - cv::resize(squareImage, squareImage, targetSize); - return squareImage; -} static cv::Mat HObject2Mat(HObject& Hobj) //HObject类型转Mat类型 { HTuple htCh; diff --git a/src/core/service/backStruct.h b/src/core/service/backStruct.h index f1d29de..ad4a911 100644 --- a/src/core/service/backStruct.h +++ b/src/core/service/backStruct.h @@ -8,9 +8,13 @@ static void createDirectoryIfNotExists(const std::string& path) { // 检查路径是否存在 if (!std::filesystem::exists(path)) { // 创建路径 - - std::filesystem::create_directories(path); - //std::cout << "已创建文件夹: " << path << std::endl; + try { + std::filesystem::create_directories(path); + //std::cout << "已创建文件夹: " << path << std::endl; + } + catch (...) { + qCritical() << "创建文件夹失败!" << QString::fromStdString(path); + } } } static void createDirectoryIfNotExists(const QString& path) { diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index e0fe693..471027b 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -13,7 +13,7 @@ enum imgSaveThreadType { class ImageSavePathFormatter { public: QString rootDir = ""; - std::string genPath(std::shared_ptr data, imgSaveThreadType type, QString customPath = "", std::vector>customParams = std::vector>()){ + QString genPath(std::shared_ptr data, imgSaveThreadType type, QString customPath = "", std::vector>customParams = std::vector>()){ QString pathTemplate = !customPath.isEmpty() ? customPath : defaultPath; QString result = pathTemplate; @@ -61,7 +61,7 @@ public: for (auto& pair : customParams) { result.replace(pair.first, pair.second); } - return result.toLocal8Bit().toStdString(); + return result; } std::string genFileName(std::shared_ptr data, imgSaveThreadType type, int index = 0, QString customFileName = "", std::vector> customParams = std::vector>(), const std::string& format = "bmp") { QString fileTemplate = !customFileName.isEmpty() ? customFileName : defaultFileName; @@ -217,33 +217,33 @@ public: ~imgSaveThreadManager() {}; imgSaveThread saveThread; void saveImage(std::shared_ptr data) { - std::string oriSavePath = _ImageSavePathFormatter.genPath(data, oriImg, data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 + QString oriSavePath = _ImageSavePathFormatter.genPath(data, oriImg, data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 createDirectoryIfNotExists(oriSavePath);//不存在此文件夹则创建 if (data->oriImgs.size() != 0) { std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, oriImg, data->oriImgs);//按规则为文件创建命名 std::shared_ptr job (new saveJob("[ORI_JOB]" + data->SNcode)); - packageData(job->imgQueue, oriSavePath, fileNames, data->oriImgs);//打包数据 + packageData(job->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->oriImgs);//打包数据 saveThread.addJob(job); } - std::string resSavePath = _ImageSavePathFormatter.genPath(data, resImg, data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 + QString resSavePath = _ImageSavePathFormatter.genPath(data, resImg, data->customPath, data->customImageSaveTemplateParams);//获取文件夹名 createDirectoryIfNotExists(resSavePath);//不存在此文件夹则创建 std::shared_ptr job(new saveJob("[RES_JOB]"+ data->SNcode)); //结果图保存 if (data->resultImgs.size() != 0) { std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, resImg, data->resultImgs);//按规则为文件创建命名 - packageData(job->imgQueue, resSavePath,fileNames, data->resultImgs);//打包数据 + packageData(job->imgQueue, resSavePath.toLocal8Bit().toStdString() ,fileNames, data->resultImgs);//打包数据 } //SEG原图 if (data->segOriginImgs.size() != 0) { std::vectorfileNames = _ImageSavePathFormatter.genFileNames(data, segImg, data->segOriginImgs);//按规则为文件创建命名 - packageData(job->imgQueue, oriSavePath, fileNames, data->segOriginImgs);//打包数据 + packageData(job->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->segOriginImgs);//打包数据 } //CLS原图 if (data->clsOriginImgs.size() != 0) { std::vectorfileNames = _ImageSavePathFormatter.genClsFileNames(data, clsImg, data->clsOriginImgs);//按规则为文件创建命名 - packageData(job->imgQueue, oriSavePath, fileNames, data->clsOriginImgs);//打包数据 + packageData(job->imgQueue, oriSavePath.toLocal8Bit().toStdString(), fileNames, data->clsOriginImgs);//打包数据 } saveThread.addJob(job, imgSaveThread::priority); //额外储存NG文件夹 diff --git a/src/launcher/GUI/front/loginWindow.cpp b/src/launcher/GUI/front/loginWindow.cpp deleted file mode 100644 index 62283bd..0000000 --- a/src/launcher/GUI/front/loginWindow.cpp +++ /dev/null @@ -1 +0,0 @@ -#include \ No newline at end of file diff --git a/src/launcher/GUI/front/pages/displayPageWidget.h b/src/launcher/GUI/front/pages/displayPageWidget.h index 3d70325..e6dc997 100644 --- a/src/launcher/GUI/front/pages/displayPageWidget.h +++ b/src/launcher/GUI/front/pages/displayPageWidget.h @@ -23,7 +23,7 @@ #include #include #include - +#include class toolBarWidget : public QWidget { Q_OBJECT public: diff --git a/src/launcher/GUI/front/pages/logPageWidget.h b/src/launcher/GUI/front/pages/logPageWidget.h index 5ef65c2..aed98aa 100644 --- a/src/launcher/GUI/front/pages/logPageWidget.h +++ b/src/launcher/GUI/front/pages/logPageWidget.h @@ -129,6 +129,7 @@ public: btnPtr->toDefault(); btn->pressed(); widgets->setCurrentIndex(index); + processCacheLog(index); }); QWidget* widget = new QWidget(); @@ -205,7 +206,24 @@ public: return QTime::currentTime().toString("HH:mm:ss.zzz"); } + void processCacheLog(int index) { + QMutexLocker globalLocker(&globalMutex); + if (logCache.find(index) == logCache.end()) return; + + FilterState& state = filterStates[index]; + QMutexLocker stateLocker(&state.mutex); + + appendColoredMessagesBatch(state.textWidget, logCache[index]); + logCache[index].clear(); + + // 自动滚动到底部 + if (state.autoScroll) { + scrollToBottom(state.textWidget); + } + } + private: + // 用于存储过滤器状态 struct FilterState { //QComboBox* levelFilter; @@ -216,14 +234,14 @@ private: mutable QMutex mutex; // 保护此状态的互斥锁 QStringList pendingMessages; // 待处理的消息队列 }; - + QMap> logCache; std::unordered_map filterStates; // 线程安全和性能优化相关 mutable QMutex globalMutex; // 全局保护锁 QTimer* batchUpdateTimer; // 批量更新定时器 - // 线程安全地添加消息 + // 添加消息 void addMessageSafe(int index, const QString& message) { QMutexLocker globalLocker(&globalMutex); @@ -254,25 +272,6 @@ private: QTextCharFormat whiteFormat; QTextCharFormat redFormat; QTextCharFormat warningFormat; - void appendColoredMessage(QPlainTextEdit* textEdit, const QString& message) { - QTextCursor cursor = textEdit->textCursor(); - cursor.movePosition(QTextCursor::End); - - // 根据关键词设置颜色 - if (message.contains("Error", Qt::CaseInsensitive) || - message.contains("错误", Qt::CaseInsensitive)) { - cursor.setCharFormat(redFormat); - } - else if (message.contains("Warning", Qt::CaseInsensitive) || - message.contains("警告", Qt::CaseInsensitive)) { - cursor.setCharFormat(warningFormat); - } - else - cursor.setCharFormat(whiteFormat); - - cursor.insertText(message + "\n"); - textEdit->setTextCursor(cursor); - } // 滚动到底部 void scrollToBottom(QPlainTextEdit* textEdit) { @@ -284,7 +283,7 @@ private: public slots: void recvStdLogMsg(QString logMsg) { QString text = getCurrentDate() + " " + getCurrentTime() + " " + logMsg; - addMessageSafe(0, text); // 使用线程安全的方法 + addMessageSafe(0, text); } void recvQtLogMsg(QString logMsg) { @@ -294,41 +293,141 @@ public slots: private slots: void processPendingMessages() { - QMutexLocker globalLocker(&globalMutex); - - bool hasUpdates = false; + + QMap pendingByIndex; int currentIndex = widgets->currentIndex(); - - for (auto& pair : filterStates) { - int index = pair.first; - FilterState& state = pair.second; - - QMutexLocker stateLocker(&state.mutex); - - if (!state.pendingMessages.isEmpty()) { - hasUpdates = true; - - // 只更新当前显示的页面,提升性能 - if (index == currentIndex) { - // 增量添加消息而不是重新过滤所有消息 - for (const QString& message : state.pendingMessages) { - appendColoredMessage(state.textWidget, message); - } - - // 自动滚动到底部 - if (state.autoScroll) { - scrollToBottom(state.textWidget); - } + { + QMutexLocker globalLocker(&globalMutex); + for (auto& pair : filterStates) { + int index = pair.first; + FilterState& state = pair.second; + QMutexLocker stateLocker(&state.mutex); + if (!state.pendingMessages.isEmpty()) { + pendingByIndex[index] = state.pendingMessages; + state.pendingMessages.clear(); } - - state.pendingMessages.clear(); } } - - // 如果没有待处理消息,停止定时器 + + bool hasUpdates = false; + + + for (auto it = pendingByIndex.begin(); it != pendingByIndex.end(); ++it) { + int index = it.key(); + const QStringList& msgs = it.value(); + if (msgs.isEmpty()) continue; + hasUpdates = true; + + FilterState& state = filterStates[index]; + + if (index == currentIndex) { + appendColoredMessagesBatch(state.textWidget, msgs); + if (state.autoScroll) { + scrollToBottom(state.textWidget); + } + } else { + // 非当前页缓存时,短暂加锁保护 logCache + QMutexLocker globalLocker(&globalMutex); + for (const auto& log : msgs) { + logCache[index].append(log); + while (logCache[index].size() > MAX_STORED_MESSAGES) + logCache[index].dequeue(); + } + } + } + if (!hasUpdates) { batchUpdateTimer->stop(); } } + +private: + //根据消息选择颜色格式 + const QTextCharFormat& formatFor(const QString& message) const { + if (message.contains("Error", Qt::CaseInsensitive) || + message.contains(QStringLiteral("错误"), Qt::CaseInsensitive)) { + return redFormat; + } else if (message.contains("Warning", Qt::CaseInsensitive) || + message.contains(QStringLiteral("警告"), Qt::CaseInsensitive)) { + return warningFormat; + } + return whiteFormat; + } + + // 批量追 + void appendColoredMessagesBatch(QPlainTextEdit* textEdit, const QStringList& messages) { + if (messages.isEmpty()) return; + + textEdit->setUpdatesEnabled(false); + + QTextCursor cursor(textEdit->document()); + cursor.movePosition(QTextCursor::End); + cursor.beginEditBlock(); + + const QTextCharFormat* currentFmt = &formatFor(messages.first()); + cursor.setCharFormat(*currentFmt); + + QString buffer; + buffer.reserve(256 * messages.size()); // 简单预留,减少 realloc + + auto flush = [&]() { + if (!buffer.isEmpty()) { + cursor.insertText(buffer); + buffer.clear(); + } + }; + + for (const QString& msg : messages) { + const QTextCharFormat* fmt = &formatFor(msg); + if (fmt != currentFmt) { + flush(); + currentFmt = fmt; + cursor.setCharFormat(*currentFmt); + } + buffer += msg; + buffer += QLatin1Char('\n'); + } + flush(); + + cursor.endEditBlock(); + textEdit->setUpdatesEnabled(true); + } + void appendColoredMessagesBatch(QPlainTextEdit* textEdit, const QQueue& messages) { + if (messages.isEmpty()) return; + + textEdit->setUpdatesEnabled(false); + + QTextCursor cursor(textEdit->document()); + cursor.movePosition(QTextCursor::End); + cursor.beginEditBlock(); + + const QTextCharFormat* currentFmt = &formatFor(messages.first()); + cursor.setCharFormat(*currentFmt); + + QString buffer; + buffer.reserve(256 * messages.size()); // 简单预留,减少 realloc + + auto flush = [&]() { + if (!buffer.isEmpty()) { + cursor.insertText(buffer); + buffer.clear(); + } + }; + + for (const QString& msg : messages) { + const QTextCharFormat* fmt = &formatFor(msg); + if (fmt != currentFmt) { + flush(); + currentFmt = fmt; + cursor.setCharFormat(*currentFmt); + } + buffer += msg; + buffer += QLatin1Char('\n'); + } + flush(); + + cursor.endEditBlock(); + textEdit->setUpdatesEnabled(true); + } }; #pragma once \ No newline at end of file diff --git a/src/launcher/GUI/front/pages/settingWidget.h b/src/launcher/GUI/front/pages/settingWidget.h index b87db5b..2d3148a 100644 --- a/src/launcher/GUI/front/pages/settingWidget.h +++ b/src/launcher/GUI/front/pages/settingWidget.h @@ -19,57 +19,12 @@ #include #include #include -#include #include "git_version.h" #include #include #include #include -#include -class hardwareInfoWidget : public QWidget { - Q_OBJECT -public: - hardwareInfoWidget() { - connect(&systemStateMonitor::getInstance(), &systemStateMonitor::addCpuUsageData, this, &hardwareInfoWidget::addCpuUsageData); - connect(&systemStateMonitor::getInstance(), &systemStateMonitor::addCpuTempData, this, &hardwareInfoWidget::addCpuTempData); - connect(&systemStateMonitor::getInstance(), &systemStateMonitor::addMemUsageData, this, &hardwareInfoWidget::addMemUsageData); - jsonMap["CPUUSAGE"] = genWaveFormWidgetJson("cpu_usage", 80, 0, 240); - waveForms["CPUUSAGE"] = new WaveFormWidget(jsonMap["CPUUSAGE"]); - layout->addWidget(waveForms["CPUUSAGE"]); - - jsonMap["MEMUSAGE"] = genWaveFormWidgetJson("mem_useage", 80, 0, 240); - waveForms["MEMUSAGE"] = new WaveFormWidget(jsonMap["MEMUSAGE"]); - layout->addWidget(waveForms["MEMUSAGE"]); - - jsonMap["CPUTEMP"] = genWaveFormWidgetJson("cpu_temp", 80, 0, 240); - waveForms["CPUTEMP"] = new WaveFormWidget(jsonMap["CPUTEMP"]); - layout->addWidget(waveForms["CPUTEMP"]); - - for (auto& widget : waveForms) { - widget->setMinimumWidth(720); - widget->setMinimumHeight(200); - widget->setFixedYrange(0, 100); - } - } -protected: - void resizeEvnt() { - - } -public slots: - void addCpuUsageData(double input) { - waveForms["CPUUSAGE"]->appendData(input); - } - void addCpuTempData(double input) { - waveForms["CPUTEMP"]->appendData(input); - } - void addMemUsageData(double input) { - waveForms["MEMUSAGE"]->appendData(input); - } -private: - QMapjsonMap; - QMap waveForms; - QGridLayout* layout = new QGridLayout(this); -}; +//#include class settingWidget :public QWidget{ Q_OBJECT @@ -377,7 +332,7 @@ public: m_layout->addWidget(consoleGroupBox); } // 硬件信息区域 - { + /*{ // 创建硬件信息分组容器 QGroupBox* hardwareGroupBox = new QGroupBox(QString::fromStdString(Translation::getInstance().translate("Hardware Information"))); hardwareGroupBox->setObjectName("hardwareGroupBox"); @@ -417,7 +372,7 @@ public: hardwareMainLayout->addWidget(&_hardwareInfoWidget); m_layout->addWidget(hardwareGroupBox); - } + }*/ // 添加底部伸缩空间 m_layout->addStretch(); @@ -431,7 +386,7 @@ protected: private: appConfig* _config; - hardwareInfoWidget _hardwareInfoWidget; + //hardwareInfoWidget _hardwareInfoWidget; //std::vector> privateJsondatas;//路径与数据 //std::vector> privateWidgets;//路径与数据 //std::vectorjsonLayouts; diff --git a/src/launcher/GUI/mainwindow.h b/src/launcher/GUI/mainwindow.h index d15fa47..e2ca057 100644 --- a/src/launcher/GUI/mainwindow.h +++ b/src/launcher/GUI/mainwindow.h @@ -29,7 +29,6 @@ #include "front/pages/pluginManagerWidget.hpp" #include "front/pages/summaryDataPage.h" #include -#include #pragma execution_character_set("utf-8") QT_BEGIN_NAMESPACE diff --git a/src/launcher/appCore.hpp b/src/launcher/appCore.hpp index 390de44..248ce56 100644 --- a/src/launcher/appCore.hpp +++ b/src/launcher/appCore.hpp @@ -8,7 +8,7 @@ // #include "interface.h" #include -#include +//#include #define HIDE_CONSOLE 1 class backEnd { @@ -60,7 +60,7 @@ class appCore : public QObject{ public: backEnd _backEnd; logService* _logService = logService::getInstance(); - systemStateMonitor* _systemStateMonitor = &systemStateMonitor::getInstance(); + //systemStateMonitor* _systemStateMonitor = &systemStateMonitor::getInstance(); appCore() { initConfig(); diff --git a/src/launcher/systemState/fetchHardwareMonitor.h b/src/launcher/systemState/fetchHardwareMonitor.h deleted file mode 100644 index 90ddc83..0000000 --- a/src/launcher/systemState/fetchHardwareMonitor.h +++ /dev/null @@ -1,181 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include - -static void findByTypeAndPrefix(const QJsonObject& obj, - const QString& type, - const QString& prefix, - QList& values){ - if (obj.contains("Type") && obj["Type"].toString() == type && - obj.contains("Text") && obj["Text"].toString().startsWith(prefix)) - { - values.append(obj["Value"].toString()); - } - - if (obj.contains("Children") && obj["Children"].isArray()) { - for (const QJsonValue& child : obj["Children"].toArray()) { - if (child.isObject()) - findByTypeAndPrefix(child.toObject(), type, prefix, values); - } - } -} -//CPU 每核心平均占用率 -static std::vector parseCpuPerCoreLoads(const QJsonObject& root){ - QList values; - findByTypeAndPrefix(root, "Load", "CPU Core", values); - std::vector result; - for (auto& val : values) { - result.push_back(val.mid(0, val.size() - 2).toDouble()); - } - return result; -} - -//CPU 每核心平均温度 -static std::vector parseCpuPerCoreTemperatures(const QJsonObject& root){ - QList values; - findByTypeAndPrefix(root, "Temperature", "CPU Core", values); - std::vector result; - result.reserve(values.size()); // 预留空间,避免扩容 - - for (const auto& val : values) { - bool ok; - double num = val.left(val.size() - 2).toDouble(&ok); - if (ok) { - result.push_back(num); - } - } - - return result; -} -// 计算整体 CPU 占用(平均值) -static double calculateOverallCpuLoad(const QJsonObject& root) { - - std::vector coreLoads = parseCpuPerCoreLoads(root); - if (coreLoads.empty()) { - return -1; // 没有数据 - } - double sum = std::accumulate(coreLoads.begin(), coreLoads.end(), 0.0); - return sum / coreLoads.size(); -} - -// 计算整体 CPU 温度(平均值) -static double calculateOverallCpuTemperature(const QJsonObject& root) { - const std::vector coreTemperatures = parseCpuPerCoreTemperatures(root); - if (coreTemperatures.empty()) { - return -1; // 没有数据 - } - double sum = std::accumulate(coreTemperatures.begin(), coreTemperatures.end(), 0.0); - return sum / coreTemperatures.size(); -} -// 计算整体 CPU 温度(最高值) -static double calculateMaxCpuTemperature(const QJsonObject& root) { - const std::vector coreTemperatures = parseCpuPerCoreTemperatures(root); - if (coreTemperatures.empty()) { - return -1; // 没有数据 - } - auto maxIt = std::max_element(coreTemperatures.begin(), coreTemperatures.end()); - double maxVal = (maxIt != coreTemperatures.end()) ? *maxIt : 0.0; - - return maxVal; -} -//内存占用率 -static double parseMemoryUsage(const QJsonObject& root){ - QList values; - findByTypeAndPrefix(root, "Load", "Memory", values); // 匹配 "Memory" - if (!values.isEmpty()) - return values.first().mid(0, values.first().size() - 2).toDouble(); // 取第一个 - return -1; -} - - -class JsonFetcher : public QObject { - Q_OBJECT -public: - - explicit JsonFetcher(QObject* parent = nullptr): - QObject(parent), manager(new QNetworkAccessManager(this)) { - connect(manager, &QNetworkAccessManager::finished, - this, &JsonFetcher::onFinished); - } - - void fetch(const QUrl& url) { - QNetworkRequest request(url); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - manager->get(request); - } - -signals: - void jsonReady(const QJsonObject& obj); - void error(const QString& err); - -private slots: - void onFinished(QNetworkReply* reply) { - if (reply->error() != QNetworkReply::NoError) { - emit error(reply->errorString()); - reply->deleteLater(); - return; - } - - QByteArray data = reply->readAll(); - reply->deleteLater(); - - QJsonParseError parseError; - QJsonDocument doc = QJsonDocument::fromJson(data, &parseError); - if (parseError.error != QJsonParseError::NoError) { - emit error(parseError.errorString()); - return; - } - - if (!doc.isObject()) { - emit error("Invalid JSON format (expected object)."); - return; - } - - QJsonObject root = filterJson(doc.object()); - emit jsonReady(root); - } - -private: - QNetworkAccessManager* manager; - - QJsonObject filterJson(const QJsonObject& obj) const { - QJsonObject filtered; - - // 只保留需要的字段 - static const QStringList allowedKeys = { - "id", "Text", "Min", "Value", "Max", "Type", "Children" - }; - - for (auto it = obj.begin(); it != obj.end(); ++it) { - if (!allowedKeys.contains(it.key())) continue; - - if (it.key() == "Children" && it.value().isArray()) { - filtered.insert("Children", filterArray(it.value().toArray())); - } - else { - filtered.insert(it.key(), it.value()); - } - } - - return filtered; - } - QJsonArray filterArray(const QJsonArray& arr) const { - QJsonArray newArr; - for (const QJsonValue& val : arr) { - if (val.isObject()) { - newArr.append(filterJson(val.toObject())); - } - else { - newArr.append(val); - } - } - return newArr; - } -}; -#pragma once \ No newline at end of file diff --git a/src/launcher/systemState/hardwareInfo.h b/src/launcher/systemState/hardwareInfo.h deleted file mode 100644 index 30afde4..0000000 --- a/src/launcher/systemState/hardwareInfo.h +++ /dev/null @@ -1,246 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -static QProcess* process = nullptr; -static HANDLE jobHandle = nullptr; - -using hwinfo::unit::bytes_to_MiB; -class hardwareInfo :public QObject { - Q_OBJECT -public: - hardwareInfo() { - const auto cpus = hwinfo::getAllCPUs(); - std::vector threads_utility = cpus[0].threadsUtilisation(); - cpuMaxThreadsUtilityRecord = std::vector(threads_utility.size(), 0); - //test(); - } - double getAvgCpuUseage() { - const auto cpus = hwinfo::getAllCPUs(); - for (const auto& cpu : cpus) { - std::vector threads_utility = cpu.threadsUtilisation(); - double result = 0; - for (int i = 0; i < threads_utility.size();i++) { - cpuMaxThreadsUtilityRecord[i] = qMax(threads_utility[i], cpuMaxThreadsUtilityRecord[i]); - result += threads_utility[i] / qMax(cpuMaxThreadsUtilityRecord[i],1.0); - } - return result / threads_utility.size() * 100.0; - } - } - double getAvgMemUseage() { - hwinfo::Memory memory; - double freeByte = memory.free_Bytes(); - double totalByte = memory.total_Bytes(); - return (1.0 - freeByte / totalByte) * 100.0; - } -#pragma region 测试 - void test() { - fmt::print( - "hwinfo is an open source, MIT licensed project that implements a platform independent " - "hardware and system information gathering API for C++.\n\n" - "If you face any issues, find bugs or if your platform is not supported yet, do not hesitate to create " - "a ticket at https://github.com/lfreist/hwinfo/issues.\n\n" - "Thanks for using hwinfo!\n\n"); - cpuCollectTest(); - osCollectTest(); - gpuCollectTest(); - memCollectTest(); - motherBoardCollectTest(); - diskCollectTest(); - netCollectTest(); - return; - } - void cpuCollectTest() { - fmt::print( - "Hardware Report:\n\n" - "----------------------------------- CPU ------------------------------------\n"); - const auto cpus = hwinfo::getAllCPUs(); - for (const auto& cpu : cpus) { - // clang-format off - fmt::print("Socket {}:\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} L1: {}, L2: {}, L3: {}\n", - cpu.id(), - "vendor:", cpu.vendor(), - "model:", cpu.modelName(), - "physical cores:", cpu.numPhysicalCores(), - "logical cores:", cpu.numLogicalCores(), - "max frequency:", cpu.maxClockSpeed_MHz(), - "regular frequency:", cpu.regularClockSpeed_MHz(), - "cache size:", cpu.L1CacheSize_Bytes(), cpu.L2CacheSize_Bytes(), cpu.L3CacheSize_Bytes()); - // clang-format on - - std::vector threads_utility = cpu.threadsUtilisation(); - std::vector threads_speed = cpu.currentClockSpeed_MHz(); - assert((threads_utility.size() == threads_speed.size())); - for (size_t thread_id = 0; thread_id != threads_utility.size(); ++thread_id) { - fmt::print("{:<20} Thread {}: {} MHz ({}%)\n", " ", thread_id, threads_speed[thread_id], - threads_utility[thread_id] * 100); - } - // fmt::print("{}\n", cpu.currentTemperature_Celsius()); - } - } - void osCollectTest() { - hwinfo::OS os; - // clang-format off - fmt::print("----------------------------------- OS ------------------------------------\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - "Operating System:", os.name(), - "version:", os.version(), - "kernel:", os.kernel(), - "architecture:", os.is32bit() ? "32 bit" : "64 bit", - "endianess:", os.isLittleEndian() ? "little endian" : "big endian"); - // clang-format on - } - void gpuCollectTest() { - auto gpus = hwinfo::getAllGPUs(); - fmt::print("----------------------------------- GPU -----------------------------------\n"); - for (const auto& gpu : gpus) { - // clang-format off - fmt::print("GPU {}:\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - gpu.id(), - "vendor:", gpu.vendor(), - "model:", gpu.name(), - "driverVersion:", gpu.driverVersion(), - "memory [MiB]:", bytes_to_MiB(gpu.memory_Bytes()), - "frequency:", gpu.frequency_MHz(), - "cores:", gpu.num_cores(), - "vendor_id:", gpu.vendor_id(), - "device_id:", gpu.device_id()); - // clang-format on - } - } - void memCollectTest() { - hwinfo::Memory memory; - // clang-format off - fmt::print("----------------------------------- RAM -----------------------------------\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - "size [MiB]:", bytes_to_MiB(memory.total_Bytes()), - "free [MiB]:", bytes_to_MiB(memory.free_Bytes()), - "available [MiB]:", bytes_to_MiB(memory.available_Bytes())); - // clang-format on - - for (const auto& module : memory.modules()) { - // clang-format off - fmt::print("RAM {}:\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - module.id, - "vendor:", module.vendor, - "model:", module.model, - "name:", module.name, - "serial-number:", module.serial_number, - "Frequency [MHz]:", module.frequency_Hz == -1 ? -1 : static_cast(module.frequency_Hz) / 1e6); - // clang-format on - } - } - void motherBoardCollectTest() { - hwinfo::MainBoard main_board; - // clang-format off - fmt::print("------------------------------- Main Board --------------------------------\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - "vendor:", main_board.vendor(), - "name:", main_board.name(), - "version:", main_board.version(), - "serial-number:", main_board.serialNumber()); - // clang-format on - - } - void diskCollectTest() { - std::vector disks = hwinfo::getAllDisks(); - fmt::print("--------------------------------- Disks -----------------------------------\n"); - if (!disks.empty()) { - int disk_counter = 0; - for (const auto& disk : disks) { - // clang-format off - fmt::print("Disk {}:\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - disk_counter++, - "vendor:", disk.vendor(), - "model:", disk.model(), - "serial-number:", disk.serialNumber(), - "size:", disk.size_Bytes(), - "free:", disk.free_size_Bytes(), - "volumes:", fmt::join(disk.volumes(), ", ")); - // clang-format on - } - } - else { - fmt::print("No Disks installed or detected\n"); - } - } - void netCollectTest() { - std::vector networks = hwinfo::getAllNetworks(); - fmt::print("--------------------------------- Networks -----------------------------------\n"); - if (!networks.empty()) { - int network_counter = 0; - for (const auto& network : networks) { - // clang-format off - if (network.ip4().size() > 0 || network.ip6().size() > 0) { - fmt::print( - "Network {}:\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n" - "{:<20} {}\n", - network_counter++, - "description:", network.description(), - "interface index:", network.interfaceIndex(), - "mac:", network.mac(), - "ipv4:", network.ip4(), - "ipv6:", network.ip6()); - } - // clang-format on - } - } - else { - fmt::print("No Networks installed or detected\n"); - } - } -#pragma endregion -private: - std::vectorcpuMaxThreadsUtilityRecord; -}; - -#pragma once \ No newline at end of file diff --git a/src/launcher/systemState/systemStateMonitor.h b/src/launcher/systemState/systemStateMonitor.h deleted file mode 100644 index e0ece84..0000000 --- a/src/launcher/systemState/systemStateMonitor.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include -#include - -class systemStateMonitor : public QThread { - Q_OBJECT -private: - // 私有构造函数 - systemStateMonitor() { - this->start(); - } - - // 禁用拷贝构造函数和赋值运算符 - systemStateMonitor(const systemStateMonitor&) = delete; - systemStateMonitor& operator=(const systemStateMonitor&) = delete; - -public: - // 获取单例实例 - static systemStateMonitor& getInstance() { - static systemStateMonitor instance; - return instance; - } - - ~systemStateMonitor() { - runFlag = false; - quit(); - wait(); - } -protected: - void run() override { - while (runFlag) { - emit addCpuUsageData(_hardwareInfo.getAvgCpuUseage()); - emit addMemUsageData(_hardwareInfo.getAvgMemUseage()); - QThread::msleep(2000); - } - - } -signals: - void addCpuUsageData(double input); - void addCpuTempData(double input); - void addMemUsageData(double input); -private: - bool runFlag = true; - hardwareInfo _hardwareInfo; -}; \ No newline at end of file diff --git a/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp b/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp index e7a4159..2f04a31 100644 --- a/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp +++ b/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp @@ -77,7 +77,7 @@ bool Hd_VirtualCamera::run()//����� } else { vector mats; - mats.push_back(cv::Mat(20960,3200,CV_8UC3,cv::Scalar(0,255,0))); + mats.push_back(cv::Mat(2096,3200,CV_8UC3,cv::Scalar(0,255,0))); queuePic.enqueue(mats); } n_mutex->unlock();