From aae60af6374f8098726d9268eecb628b93499da7 Mon Sep 17 00:00:00 2001 From: RCi <15089880081@163.com> Date: Mon, 25 Aug 2025 15:53:05 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E7=89=88=E6=9C=AC=E5=A4=87?= =?UTF-8?q?=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 26 ++ CMakeUserPresets.json | 42 +- include/global.h | 1 + .../simpleTools/eulerCoordinateAlgo.h | 0 .../simpleTools/fileManager.cpp | 0 .../simpleTools/fileManager.h | 0 .../simpleTools/lightSource.hpp | 0 {src/Core => include}/simpleTools/sharedMem.h | 0 .../simpleTools/simpleSiemensTcp.hpp | 0 .../Core => include}/simpleTools/stringAlgo.h | 0 .../simpleTools/windowsHardwareCtrl.hpp | 0 .../Core => include}/simpleTools/writeCsv.hpp | 0 .../simpleTools/writeExcel.cpp | 0 .../Core => include}/simpleTools/writeExcel.h | 0 include/sql/qSqlBase.h | 313 +++++++------- rpcModule/rpc_finsTcp/rpc_finsTcp.cpp | 6 +- src/Core/CMakeLists.txt | 7 +- src/Core/back/triggerManager.cpp | 1 - src/Core/back/triggerManager.h | 5 +- src/Core/detProcess.hpp | 4 +- src/Core/handleAi/handleAiModel.cpp | 45 -- src/Core/handleAi/handleAiModel.h | 42 +- src/Core/handleAi/handleAiModelList.hpp | 6 - src/core/back/CLIManager.h | 75 +--- src/{core => }/fuck-u-code-windows-amd64.exe | Bin src/launcher/CMakeLists.txt | 3 +- .../GUI/front/pages/configSettingWidget.h | 58 ++- src/launcher/GUI/front/pages/historyWidget.h | 3 +- .../GUI/front/pages/sqlControlWidget.h | 21 +- .../GUI/front/pages/summary_data_page.h | 296 +------------- src/launcher/GUI/mainwindow.cpp | 6 +- src/launcher/GUI/mainwindow.h | 3 +- .../GUI/simpleTools/eulerCoordinateAlgo.h | 51 --- src/launcher/GUI/simpleTools/fileManager.cpp | 24 -- src/launcher/GUI/simpleTools/fileManager.h | 386 ------------------ src/launcher/GUI/simpleTools/lightSource.hpp | 96 ----- src/launcher/GUI/simpleTools/sharedMem.h | 84 ---- .../GUI/simpleTools/simpleSiemensTcp.hpp | 110 ----- src/launcher/GUI/simpleTools/stringAlgo.h | 16 - .../GUI/simpleTools/windowsHardwareCtrl.hpp | 100 ----- src/launcher/GUI/simpleTools/writeCsv.hpp | 27 -- src/launcher/GUI/uiModule/jsonExamlpe.json | 13 + src/launcher/GUI/uiModule/uiChart_WaveForm.h | 309 ++++++++++++++ .../GUI/uiModule/uiModule_dumpToExcel.h | 2 +- .../GUI/uiModule/uiModule_imageView.h | 8 +- src/launcher/appConfig/appConfig.h | 1 + src/launcher/appCore.hpp | 4 - .../hardwareInfo/fetchHardwareMonitor.h | 181 ++++++++ src/launcher/hardwareInfo/hardwareInfo.h | 365 +++++++++++++++++ src/launcher/main.cpp | 62 +-- src/mission/581-Mfd_djy_sd/581-Mfd.h | 2 +- src/mission/581-Mfd_yh_mh_hh/581-Mfd.h | 4 +- src/mission/581-Ruke/581-Ruke.h | 1 + 53 files changed, 1197 insertions(+), 1612 deletions(-) rename {src/Core => include}/simpleTools/eulerCoordinateAlgo.h (100%) rename {src/Core => include}/simpleTools/fileManager.cpp (100%) rename {src/Core => include}/simpleTools/fileManager.h (100%) rename {src/Core => include}/simpleTools/lightSource.hpp (100%) rename {src/Core => include}/simpleTools/sharedMem.h (100%) rename {src/Core => include}/simpleTools/simpleSiemensTcp.hpp (100%) rename {src/Core => include}/simpleTools/stringAlgo.h (100%) rename {src/Core => include}/simpleTools/windowsHardwareCtrl.hpp (100%) rename {src/Core => include}/simpleTools/writeCsv.hpp (100%) rename {src/Core => include}/simpleTools/writeExcel.cpp (100%) rename {src/Core => include}/simpleTools/writeExcel.h (100%) delete mode 100644 src/Core/handleAi/handleAiModel.cpp delete mode 100644 src/Core/handleAi/handleAiModelList.hpp rename src/{core => }/fuck-u-code-windows-amd64.exe (100%) delete mode 100644 src/launcher/GUI/simpleTools/eulerCoordinateAlgo.h delete mode 100644 src/launcher/GUI/simpleTools/fileManager.cpp delete mode 100644 src/launcher/GUI/simpleTools/fileManager.h delete mode 100644 src/launcher/GUI/simpleTools/lightSource.hpp delete mode 100644 src/launcher/GUI/simpleTools/sharedMem.h delete mode 100644 src/launcher/GUI/simpleTools/simpleSiemensTcp.hpp delete mode 100644 src/launcher/GUI/simpleTools/stringAlgo.h delete mode 100644 src/launcher/GUI/simpleTools/windowsHardwareCtrl.hpp delete mode 100644 src/launcher/GUI/simpleTools/writeCsv.hpp create mode 100644 src/launcher/GUI/uiModule/jsonExamlpe.json create mode 100644 src/launcher/GUI/uiModule/uiChart_WaveForm.h create mode 100644 src/launcher/hardwareInfo/fetchHardwareMonitor.h create mode 100644 src/launcher/hardwareInfo/hardwareInfo.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 05364f3..32c3d75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,6 +201,32 @@ if(ON) else() SET( ${child}_target_link "libbreakpad" ) endif() + elseif(${child} MATCHES "hwinfo") + if(CMAKE_BUILD_TYPE MATCHES "Debug") + SET( ${child}_target_link + "fmtd" + "hwinfo_battery_d" + "hwinfo_cpu_d" + "hwinfo_disk_d" + "hwinfo_gpu_d" + "hwinfo_mainboard_d" + "hwinfo_network_d" + "hwinfo_gpu_d" + "hwinfo_os_d" + "hwinfo_ram_d") + else() + SET( ${child}_target_link + "fmt" + "hwinfo_battery" + "hwinfo_cpu" + "hwinfo_disk" + "hwinfo_gpu" + "hwinfo_mainboard" + "hwinfo_network" + "hwinfo_gpu" + "hwinfo_os" + "hwinfo_ram") + endif() else() SET( ${child}_target_link "" ) endif() diff --git a/CMakeUserPresets.json b/CMakeUserPresets.json index d8b2cfb..29c3c99 100644 --- a/CMakeUserPresets.json +++ b/CMakeUserPresets.json @@ -21,56 +21,20 @@ "CMAKE_BUILD_TYPE": "Release" } }, - { - "hidden": true, - "name": "T", - "inherits": "Qt", - "environment": { - "QTDIR": "D:/ds-628/env/qt5" - }, - "architecture": { - "strategy": "external", - "value": "x64" - }, - "generator": "Ninja", - "vendor": { - "qt-project.org/Version": { - "checksum": "E5+uagywx2jwhIiLSAFSbiyrNiM=" - } - } - }, - { - "hidden": true, - "name": "12", - "inherits": "Qt", - "environment": { - "QTDIR": "D:/ds-628/env/qt5" - }, - "architecture": { - "strategy": "external", - "value": "x64" - }, - "generator": "Ninja", - "vendor": { - "qt-project.org/Version": { - "checksum": "hXZNUGAPmLqcCieREfoGZb1R80I=" - } - } - }, { "hidden": true, "name": "Qt-Default", - "inherits": "T", + "inherits": null, "vendor": { "qt-project.org/Default": { - "checksum": "GUdpNFihrz9Et4EYDqQf1Vgr0p8=" + "checksum": "VoalogTkyWuFomeO1TLFx0olLJ4=" } } } ], "vendor": { "qt-project.org/Presets": { - "checksum": "Nmw6b/F/7ijfM6TjQ4QyFb3ylIM=" + "checksum": "Isp/aHJ+aeyUOO6+L/cRr4cRTww=" } } } \ No newline at end of file diff --git a/include/global.h b/include/global.h index f9de8fd..8ced991 100644 --- a/include/global.h +++ b/include/global.h @@ -10,6 +10,7 @@ #pragma execution_character_set("utf-8") const std::string softwareVersion = "2.0.2"; const std::string euiJsonVersion = "1.0.6"; +#define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 #define saveImgEnable 1 #define switchToTongYongUi 1 //是否切换到通用UI界面 #define skipLogin 1 //是否跳过登录界面 diff --git a/src/Core/simpleTools/eulerCoordinateAlgo.h b/include/simpleTools/eulerCoordinateAlgo.h similarity index 100% rename from src/Core/simpleTools/eulerCoordinateAlgo.h rename to include/simpleTools/eulerCoordinateAlgo.h diff --git a/src/Core/simpleTools/fileManager.cpp b/include/simpleTools/fileManager.cpp similarity index 100% rename from src/Core/simpleTools/fileManager.cpp rename to include/simpleTools/fileManager.cpp diff --git a/src/Core/simpleTools/fileManager.h b/include/simpleTools/fileManager.h similarity index 100% rename from src/Core/simpleTools/fileManager.h rename to include/simpleTools/fileManager.h diff --git a/src/Core/simpleTools/lightSource.hpp b/include/simpleTools/lightSource.hpp similarity index 100% rename from src/Core/simpleTools/lightSource.hpp rename to include/simpleTools/lightSource.hpp diff --git a/src/Core/simpleTools/sharedMem.h b/include/simpleTools/sharedMem.h similarity index 100% rename from src/Core/simpleTools/sharedMem.h rename to include/simpleTools/sharedMem.h diff --git a/src/Core/simpleTools/simpleSiemensTcp.hpp b/include/simpleTools/simpleSiemensTcp.hpp similarity index 100% rename from src/Core/simpleTools/simpleSiemensTcp.hpp rename to include/simpleTools/simpleSiemensTcp.hpp diff --git a/src/Core/simpleTools/stringAlgo.h b/include/simpleTools/stringAlgo.h similarity index 100% rename from src/Core/simpleTools/stringAlgo.h rename to include/simpleTools/stringAlgo.h diff --git a/src/Core/simpleTools/windowsHardwareCtrl.hpp b/include/simpleTools/windowsHardwareCtrl.hpp similarity index 100% rename from src/Core/simpleTools/windowsHardwareCtrl.hpp rename to include/simpleTools/windowsHardwareCtrl.hpp diff --git a/src/Core/simpleTools/writeCsv.hpp b/include/simpleTools/writeCsv.hpp similarity index 100% rename from src/Core/simpleTools/writeCsv.hpp rename to include/simpleTools/writeCsv.hpp diff --git a/src/Core/simpleTools/writeExcel.cpp b/include/simpleTools/writeExcel.cpp similarity index 100% rename from src/Core/simpleTools/writeExcel.cpp rename to include/simpleTools/writeExcel.cpp diff --git a/src/Core/simpleTools/writeExcel.h b/include/simpleTools/writeExcel.h similarity index 100% rename from src/Core/simpleTools/writeExcel.h rename to include/simpleTools/writeExcel.h diff --git a/include/sql/qSqlBase.h b/include/sql/qSqlBase.h index 8eb6cfd..cdbbd0d 100644 --- a/include/sql/qSqlBase.h +++ b/include/sql/qSqlBase.h @@ -24,16 +24,20 @@ #include #include #include +#include +#include +#include class SQLiteDB { public: - SQLiteDB(const QString& dbPath, const QString& dbName) - : m_dbName(dbName), m_dbPath(dbPath) { + QSqlDatabase db; + SQLiteDB(const QString& dbPath) + : dbPath(dbPath){ connect(); } ~SQLiteDB() { disconnect(); }; // 执行无返回值的SQL语句(如插入、删除、更新) bool execute(const QString& queryStr, const QVariantList& args = {}) { - QSqlQuery query; + QSqlQuery query(db); query.prepare(queryStr); for (int i = 0; i < args.size(); ++i) { @@ -50,7 +54,7 @@ public: // 查询数据,返回结果集 QList> query(const QString& queryStr, const QVariantList& args = {}) { QList> results; - QSqlQuery query; + QSqlQuery query(db); query.prepare(queryStr); for (int i = 0; i < args.size(); ++i) { @@ -75,7 +79,7 @@ public: } // 检查数据库是否已连接 bool isConnected() const { - return m_db.isOpen(); + return db.isOpen(); } ////////////////BASE////////////////////// bool createTable(const QString& tableName, const QList>& columns) { @@ -93,7 +97,7 @@ public: QString sql = QString("CREATE TABLE IF NOT EXISTS \"%1\" (%2)") .arg(tableName) .arg(columnDefinitions.join(", ")); - QSqlQuery query(m_db); + QSqlQuery query(db); bool res = query.exec(sql); return res; } @@ -101,7 +105,7 @@ public: std::vector tables; // 查询所有表名,排除sqlite系统表 QString sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"; - QSqlQuery query(m_db); + QSqlQuery query(db); if (!query.exec(sql)) { qDebug() << "getTables failed:" << query.lastError().text(); return tables; @@ -126,7 +130,7 @@ public: // 构造 SQL 语句 QString sql = QString("ALTER TABLE \"%1\" ADD COLUMN \"%2\" %3").arg(tableName, columnName, columnType); - QSqlQuery query(m_db); + QSqlQuery query(db); query.prepare(sql); // 执行 SQL 语句 @@ -177,10 +181,10 @@ public: qDebug() << "Generated SQL: " << sql; - QSqlQuery query(m_db); + QSqlQuery query(db); // 检查数据库连接 - if (!m_db.isOpen()) { + if (!db.isOpen()) { qDebug() << "Database is not open!"; return false; } @@ -222,10 +226,10 @@ public: qDebug() << "Generated SQL: " << sql; - QSqlQuery query(m_db); + QSqlQuery query(db); // 检查数据库连接 - if (!m_db.isOpen()) { + if (!db.isOpen()) { qDebug() << "Database is not open!"; return false; } @@ -256,7 +260,7 @@ public: .arg(tableName) .arg(whereClauses.join(" AND ")); - QSqlQuery query(m_db); + QSqlQuery query(db); query.prepare(sql); // 绑定条件参数 @@ -293,10 +297,10 @@ public: qDebug() << "Generated SQL: " << sql; - QSqlQuery query(m_db); + QSqlQuery query(db); // 检查数据库连接 - if (!m_db.isOpen()) { + if (!db.isOpen()) { qDebug() << "Database is not open!"; return {}; } @@ -332,7 +336,7 @@ public: // 查询表中的所有数据 QString csvFileName = filePath; QString sql = QString("SELECT * FROM \"%1\"").arg(tableName); - QSqlQuery query(m_db); + QSqlQuery query(db); if (!query.exec(sql)) { qCritical() << "Query execution failed: " << query.lastError().text(); @@ -386,23 +390,23 @@ public: private: bool connect() { + m_connectionName = QUuid::createUuid().toString(); // 检查数据库文件是否存在 - if (!QFile::exists(m_dbPath + m_dbName + ".db")) { - QDir().mkpath(m_dbPath); - qDebug() << "Database file does not exist. Creating a new database:" << m_dbName; + if (!QFile::exists(dbPath)) { + QFileInfo fi(dbPath); + QDir().mkpath(fi.absolutePath()); + qDebug() << "Database file does not exist. Creating a new database:" << dbPath; } - QCoreApplication::addLibraryPath("./"); - // 添加 SQLite 数据库驱动 - m_db = QSqlDatabase::addDatabase("QSQLITE"); - m_db.setDatabaseName(m_dbPath + m_dbName + ".db"); - + db = QSqlDatabase::addDatabase("QSQLITE", m_connectionName); + db.setDatabaseName(dbPath); + // 打开数据库 - if (!m_db.open()) { - qCritical() << "Failed to open or create database:" << m_db.lastError().text(); + if (!db.open()) { + qCritical() << "Failed to open or create database:" << db.lastError().text(); return false; } - qDebug() << "Connected to SQLite database:" << m_dbPath + m_dbName; + qDebug() << "Connected to SQLite database:" << dbPath; createTable("setting", { {"id","INTEGER PRIMARY KEY AUTOINCREMENT"} , @@ -411,23 +415,20 @@ private: } // 关闭数据库连接 void disconnect() { - if (m_db.isOpen()) { - m_db.close(); + QSqlDatabase::removeDatabase(m_connectionName); + if (db.isOpen()) { + db.close(); qDebug() << "Database closed."; } } - QString m_dbName; - QString m_dbPath; - QSqlDatabase m_db; + QString m_connectionName; + QString dbPath; }; -class CsvWriter -{ +class CsvWriter : public QThread{ public: - CsvWriter(SQLiteDB* database_ptr = nullptr) - { - try - { + CsvWriter(){ + try{ m_json = readJsonFromPath("./sqldrivers/sqliteCfg.json"); for (auto& data : m_json["数据列表"]) { db_InitColumns.append({ QString::fromStdString(data),"TEXT" }); @@ -446,115 +447,36 @@ public: isNgDepends.push_back(QString::fromStdString(data)); } } - catch (const std::exception&) - { + catch (const std::exception&){ std::cerr << "readJsonFromPath error" << std::endl; } - init(database_ptr); + init(); } - ~CsvWriter() - { + ~CsvWriter(){ //stopAutoExport(); } std::mapcsvAndChartLink; - bool addtData(const QString& snCode, const std::map& data) { - try { - if (snCode.isEmpty()) { - qWarning() << "addtData: snCode is empty."; - return false; - } - if (data.empty()) { - qWarning() << "addtData: data is empty."; - return false; - } - std::lock_guard locker(_mutex); - QString currentProcessCsvName = getCurrentProcessCsvName(); - if (currentProcessCsvName != currentProcessCsvNameCache) { - if (!_db->createTable(currentProcessCsvName, db_InitColumns)) { - qWarning() << "addtData: Failed to create table:" << currentProcessCsvName; - return false; - } - currentProcessCsvNameCache = currentProcessCsvName; - } - - // 获取当前表的所有列名 - QSqlQuery colQuery; - QString colSql = QString("PRAGMA table_info(\"%1\")").arg(currentProcessCsvName); - QList tableColumns; - if (colQuery.exec(colSql)) { - while (colQuery.next()) { - tableColumns.append(colQuery.value(1).toString()); - } - } - - // 检查 data 中的 key 是否在表结构中,不在则新增列 - for (const auto& kv : data) { - if (!tableColumns.contains(kv.first)) { - // 默认新增为 TEXT 类型 - if (!_db->addColumn(currentProcessCsvName, kv.first, "TEXT")) { - qWarning() << "addtData: Failed to add column:" << kv.first << "to table:" << currentProcessCsvName; - // 可选择 return false 或继续 - } - } - } - - auto res = _db->_search(currentProcessCsvName, {}, { {"条码",snCode} }); - - QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); // 精度提升到毫秒 - bool opResult = false; - - if (res.empty()) { - auto lastRes = _db->_search(getLastProcessCsvName(), {}, { {"条码",snCode} }); - if (lastRes.empty()) { - // 插入新数据 - std::map insertData = data; - insertData["条码"] = snCode; - insertData["创建时间"] = nowTime; - insertData["修改时间"] = nowTime; - opResult = _db->_insert(currentProcessCsvName, insertData); - if (!opResult) { - qWarning() << "addtData: Insert failed for table:" << currentProcessCsvName << "snCode:" << snCode; - } - } else { - // 更新过去的数据 - std::map updateData = data; - updateData["修改时间"] = nowTime; - opResult = _db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} }); - if (!opResult) { - qWarning() << "addtData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode; - } - } - } else { - // 更新当前数据 - std::map updateData = data; - updateData["修改时间"] = nowTime; - opResult = _db->_update(getCurrentProcessCsvName(), updateData, { {"条码",snCode} }); - if (!opResult) { - qWarning() << "addtData: Update failed for table:" << getCurrentProcessCsvName() << "snCode:" << snCode; - } - } - - if (timer.elapsed() > m_intervalMs) { - exportCsv(); - timer.start(); - } - return opResult; - } catch (const std::exception& ex) { - qCritical() << "addtData: Exception caught:" << ex.what(); - return false; - } catch (...) { - qCritical() << "addtData: Unknown exception caught."; - return false; + void addData(QString snCode, std::map data) { + + if (snCode.isEmpty()) { + qWarning() << "addtData: snCode is empty."; + return; } + if (data.empty()) { + qWarning() << "addtData: data is empty."; + return; + } + queue.enqueue(std::make_pair(snCode, data)); + this->start(); } bool isNewData(const QString& snCode) { std::lock_guard locker(_mutex); - auto res = _db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} }); + auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} }); return res.empty(); } bool isNgData(const QString& snCode) { std::lock_guard locker(_mutex); - auto res = _db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} }); + auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} }); if (res.empty() == true) return false; for (auto& data : isNgDepends) { @@ -563,11 +485,99 @@ public: } return false; } + void run() override{ + while (queue.size() > 0) { + auto val = queue.dequeue(); + try { + auto snCode = val.first; + auto data = val.second; + QString currentProcessCsvName = getCurrentProcessCsvName(); + if (currentProcessCsvName != currentProcessCsvNameCache) { + if (!db->createTable(currentProcessCsvName, db_InitColumns)) { + qWarning() << "addtData: Failed to create table:" << currentProcessCsvName; + return; + } + currentProcessCsvNameCache = currentProcessCsvName; + } + // 获取当前表的所有列名 + QSqlQuery colQuery(db->db); + QString colSql = QString("PRAGMA table_info(\"%1\")").arg(currentProcessCsvName); + QList tableColumns; + if (colQuery.exec(colSql)) { + while (colQuery.next()) { + tableColumns.append(colQuery.value(1).toString()); + } + } + + // 检查 data 中的 key 是否在表结构中,不在则新增列 + for (const auto& kv : data) { + if (!tableColumns.contains(kv.first)) { + // 默认新增为 TEXT 类型 + if (!db->addColumn(currentProcessCsvName, kv.first, "TEXT")) { + qWarning() << "addtData: Failed to add column:" << kv.first << "to table:" << currentProcessCsvName; + // 可选择 return false 或继续 + } + } + } + + auto res = db->_search(currentProcessCsvName, {}, { {"条码",snCode} }); + + QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); // 精度提升到毫秒 + bool opResult = false; + + if (res.empty()) { + auto lastRes = db->_search(getLastProcessCsvName(), {}, { {"条码",snCode} }); + if (lastRes.empty()) { + // 插入新数据 + std::map insertData = data; + insertData["条码"] = snCode; + insertData["创建时间"] = nowTime; + insertData["修改时间"] = nowTime; + opResult = db->_insert(currentProcessCsvName, insertData); + if (!opResult) { + qWarning() << "addtData: Insert failed for table:" << currentProcessCsvName << "snCode:" << snCode; + } + } + else { + // 更新过去的数据 + std::map updateData = data; + updateData["修改时间"] = nowTime; + opResult = db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} }); + if (!opResult) { + qWarning() << "addtData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode; + } + } + } + else { + // 更新当前数据 + std::map updateData = data; + updateData["修改时间"] = nowTime; + opResult = db->_update(getCurrentProcessCsvName(), updateData, { {"条码",snCode} }); + if (!opResult) { + qWarning() << "addtData: Update failed for table:" << getCurrentProcessCsvName() << "snCode:" << snCode; + } + } + + //if (timer.elapsed() > m_intervalMs) { + // exportCsv(); + // timer.start(); + //} + } + catch (const std::exception& ex) { + qCritical() << "addtData: Exception caught:" << ex.what(); + } + catch (...) { + qCritical() << "addtData: Unknown exception caught."; + } + + } + } private: + QQueue>> queue; std::vector isNgDepends; QQueue> > addDataCacheQueue; std::mutex _mutex; - SQLiteDB* _db; + SQLiteDB* db; int m_intervalMs = 10000; QElapsedTimer timer; QString currentProcessCsvNameCache; @@ -579,36 +589,19 @@ private: {"修改时间", "TEXT"}, {"CT", "TEXT"}, }; - //void run() - //{ - // init(); - // while (m_running == true) { - // QThread::msleep(m_intervalMs); - // while (addDataCacheQueue.empty() == false) - // { - // auto data = addDataCacheQueue.dequeue(); - // addtData(data.first, data.second); - // } - // exportCsv(); - // } - // delete _db; - //} - void init(SQLiteDB* database_ptr = nullptr){ + void init(){ std::lock_guard locker(_mutex); - if (database_ptr == nullptr) - _db = new SQLiteDB("./sqlDatabse/", "database"); - else - _db = database_ptr; - if (!_db->createTable(getLastProcessCsvName(), db_InitColumns)) { + db = new SQLiteDB(globalDatabasePth); + if (!db->createTable(getLastProcessCsvName(), db_InitColumns)) { qDebug() << "Failed to create table " << getLastProcessCsvName(); } currentProcessCsvNameCache = getCurrentProcessCsvName(); - if (!_db->createTable(currentProcessCsvNameCache, db_InitColumns)) { + if (!db->createTable(currentProcessCsvNameCache, db_InitColumns)) { qDebug() << "Failed to create table " << currentProcessCsvNameCache; } for (auto& data : db_newCol) { - _db->addColumn(getLastProcessCsvName(), data.first, data.second); - _db->addColumn(getCurrentProcessCsvName(), data.first, data.second); + db->addColumn(getLastProcessCsvName(), data.first, data.second); + db->addColumn(getCurrentProcessCsvName(), data.first, data.second); } timer.start(); } @@ -676,12 +669,12 @@ private: void exportCsv(){ //std::lock_guard locker(_mutex); QString name = getLastProcessCsvName(); - _db->exportTableToCSV(name, "./csv/"+ name +".csv", _mutex); + db->exportTableToCSV(name, "./csv/"+ name +".csv", _mutex); name = getCurrentProcessCsvName(); - _db->exportTableToCSV(name, "./csv/" + name + ".csv", _mutex); + db->exportTableToCSV(name, "./csv/" + name + ".csv", _mutex); QString currentProcessCsvName = getCurrentProcessCsvName(); if (currentProcessCsvName != currentProcessCsvNameCache) - if (!_db->createTable(currentProcessCsvName, db_InitColumns)) { + if (!db->createTable(currentProcessCsvName, db_InitColumns)) { return; } else diff --git a/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp b/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp index a5f8c50..a23299d 100644 --- a/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp +++ b/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp @@ -61,8 +61,9 @@ bool rpc_finsTcp::readData(std::vector& vec_mat, QByteArray& data) ptr = new JsonRpcClient("127.0.0.1", 9000); read_JsonRpcClient[data] = ptr; } - // auto result = read_JsonRpcClient[data]->call("excuteCli", QJsonArray{QString(data)}, "finstcp"); - data = ptr->finsReadCall("excuteCli", QString(data), "finstcp"); + auto result = read_JsonRpcClient[data]->call("excuteCli", QJsonArray{ QString(data) }, "finstcp"); + data = variantListToByteArray(result); + //data = ptr->finsReadCall("excuteCli", QString(data), "finstcp"); return true; } bool ifRetryCMD = false; @@ -316,7 +317,6 @@ QByteArray JsonRpcClient::finsReadCall(const QString& method, const QString& par QByteArray responseData = socket_.readAll(); - // 使用 nlohmann json 替代 Qt 解析 try { if (responseData.contains("error")) { //qWarning() << "[JsonRpcClient] Error:" << QString::fromStdString(respJson["error"].dump()); diff --git a/src/Core/CMakeLists.txt b/src/Core/CMakeLists.txt index be166f3..5ab2d26 100644 --- a/src/Core/CMakeLists.txt +++ b/src/Core/CMakeLists.txt @@ -1,7 +1,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) string(TIMESTAMP RUN_TIME) message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) -set(DLL_NAMES "halcon" "opencv" "sqlite" "handdleAI""myTools" "mvs" "3DAI" "python") +set(DLL_NAMES "halcon" "opencv" "handdleAI""myTools" "mvs") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) @@ -53,6 +53,7 @@ FILE(GLOB_RECURSE APP_HEADERPP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" ) FILE(GLOB_RECURSE APP_HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE(GLOB_RECURSE APP_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") FILE(GLOB_RECURSE APP_UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.ui") +FILE(GLOB_RECURSE APP_UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cc") INCLUDE_DIRECTORIES(${CMAEK_CURRENT_BINARY_DIR}) set(RESOURCES_DIR ${CMAKE_SOURCE_DIR}"/resources/resources.qrc") @@ -84,7 +85,9 @@ SET(ALL_DLL ${lib_list} ) message("all_lib :" ${ALL_DLL}) -target_link_libraries(${CURRENT_FOLDER} ${ALL_DLL} ) +target_link_libraries( + ${CURRENT_FOLDER} + PRIVATE ${ALL_DLL}) string(TIMESTAMP RUN_TIME) message("C++ Standard: ${CMAKE_CXX_STANDARD}") message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/src/Core/back/triggerManager.cpp b/src/Core/back/triggerManager.cpp index 48547b7..80a52e5 100644 --- a/src/Core/back/triggerManager.cpp +++ b/src/Core/back/triggerManager.cpp @@ -4,7 +4,6 @@ #include //#include #include -#include triggerManager::triggerManager(detProcess* _detProcessIn, qtFuncBridge* bridgeIn,nlohmann::ordered_json& triggerJson) { diff --git a/src/Core/back/triggerManager.h b/src/Core/back/triggerManager.h index ab8f446..c85dff3 100644 --- a/src/Core/back/triggerManager.h +++ b/src/Core/back/triggerManager.h @@ -215,7 +215,10 @@ public: _triggerCallbackStruct.triggerAddress = triggerAddress; _triggerCallbackStruct.triggerValue = triggerValue; _triggerCallbackStruct.func = func; - _triggerCallbackStruct.funcName = funcName; + if (funcName == "") + _triggerCallbackStruct.funcName = std::to_string(triggerAddress) + "触发"; + else + _triggerCallbackStruct.funcName = funcName; for (auto& _struct : readAllCmds) { if (triggerAddress >= _struct.startPos && triggerAddress < _struct.startPos + _struct.readLength) { triggerCallbackFuncs[_struct.readAllCmd].push_back(_triggerCallbackStruct); diff --git a/src/Core/detProcess.hpp b/src/Core/detProcess.hpp index adc1c05..8005972 100644 --- a/src/Core/detProcess.hpp +++ b/src/Core/detProcess.hpp @@ -14,8 +14,8 @@ public: CLIManager* _cliManager; // 命令行接口管理器 bool initOnce = false; detProcess(){ - dataBase = new SQLiteDB("./sqlDatabse/", "eui_db"); - _csvWriter = new CsvWriter(dataBase); + dataBase = new SQLiteDB(globalDatabasePth); + _csvWriter = new CsvWriter(); } void initConfig(nlohmann::ordered_json& jsonIn, qtFuncBridge* bridgeIn) { diff --git a/src/Core/handleAi/handleAiModel.cpp b/src/Core/handleAi/handleAiModel.cpp deleted file mode 100644 index fc5fa46..0000000 --- a/src/Core/handleAi/handleAiModel.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - - -void handleAiModelManager::handleAiModelManager::run() -{ - if (init == true || jsonAvailable == false) - return; - handleAiModelinitialization(this); - if (enableHandleAiModel == true) { - std::vector> futures; - for (auto& model : segModels) - { - futures.push_back(std::async(std::launch::async, &handleAiModelSeg::init, model.second)); - bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); - } - for (auto& model : clsModels) - { - futures.push_back(std::async(std::launch::async, &handleAiModelCls::init, model.second)); - bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); - } - for (auto& model : detModels) - { - futures.push_back(std::async(std::launch::async, &handleAiModelDet::init, model.second)); - bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); - } - for (int i =0 ;i< futures.size();i++) - { - futures[i].wait(); - std::string result = futures[i].get(); - bridge->loadingWindow_appendLog( - QString::fromStdString(fileManager::getFileName(result)) + "成功( " + QString::number(i+1)+"/"+QString::number(futures.size()) + ")", "green"); - qDebug() << QString::fromStdString(fileManager::getFileName(result) + "成功"); - std::cout << fileManager::getFileName(result) + "成功" << std::endl; - } - init = true; - status = InitOK; - } - else { - status = InitOK; - } - - - -} \ No newline at end of file diff --git a/src/Core/handleAi/handleAiModel.h b/src/Core/handleAi/handleAiModel.h index 605d8b5..2a54201 100644 --- a/src/Core/handleAi/handleAiModel.h +++ b/src/Core/handleAi/handleAiModel.h @@ -37,7 +37,6 @@ public: gpuMutex->unlock(); return res; } -//private: handdleAI::pSegmentation* segPtr = nullptr; }; class handleAiModelCls{ @@ -95,7 +94,6 @@ public: gpuMutex->unlock(); return true; } -private: handdleAI::pDetection* detPtr; }; class handleAiModelManager :public serviceModule{ @@ -178,7 +176,45 @@ public: return mapResult->second; } - void run(); + void run(){ + if (init == true || jsonAvailable == false) + return; + if (enableHandleAiModel == true) { + std::vector> futures; + for (auto& model : segModels) + { + futures.push_back(std::async(std::launch::async, &handleAiModelSeg::init, model.second)); + bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); + } + for (auto& model : clsModels) + { + futures.push_back(std::async(std::launch::async, &handleAiModelCls::init, model.second)); + bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); + } + for (auto& model : detModels) + { + futures.push_back(std::async(std::launch::async, &handleAiModelDet::init, model.second)); + bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); + } + for (int i = 0; i < futures.size(); i++) + { + futures[i].wait(); + std::string result = futures[i].get(); + bridge->loadingWindow_appendLog( + QString::fromStdString(fileManager::getFileName(result)) + "成功( " + QString::number(i + 1) + "/" + QString::number(futures.size()) + ")", "green"); + qDebug() << QString::fromStdString(fileManager::getFileName(result) + "成功"); + std::cout << fileManager::getFileName(result) + "成功" << std::endl; + } + init = true; + status = InitOK; + } + else { + status = InitOK; + } + + + + } ~handleAiModelManager() { if (enableHandleAiModel) { diff --git a/src/Core/handleAi/handleAiModelList.hpp b/src/Core/handleAi/handleAiModelList.hpp deleted file mode 100644 index 25efffe..0000000 --- a/src/Core/handleAi/handleAiModelList.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -static void handleAiModelinitialization(handleAiModelManager*ptr) -{ - -} -#pragma once \ No newline at end of file diff --git a/src/core/back/CLIManager.h b/src/core/back/CLIManager.h index 91f87f8..7b48c55 100644 --- a/src/core/back/CLIManager.h +++ b/src/core/back/CLIManager.h @@ -26,77 +26,6 @@ public: CLIManager(ServiceManager* _serviceManagerIn,qtFuncBridge* bridgeIn) :_serviceManager(_serviceManagerIn), bridge(bridgeIn) {} ~CLIManager() {} - -#pragma region trash -// void cliCommands(const std::string& command,std::vectorargs) { -// auto it = commandMap.find(command); -// if (it != commandMap.end()) { -// switch (it->second) { -// case Trigger: -// trigger(args); -// break; -// case Evaluate: -// evaluate(args); -// break; -// default: -// break; -// } -// } else { -// std::cerr << "Unknown command: " << command << std::endl; -// } -// } -// void trigger(std::vector&args) { -// try { -//#pragma region 错误检查 -// if (_serviceManager->_triggerManager == nullptr) { -// std::cerr << "Trigger manager is not initialized." << std::endl; -// return; -// } -// if (args.size() < 1) { -// std::cerr << "Insufficient arguments for trigger command." << std::endl; -// return; -// } -// if (args[0].type() != QVariant::String) { -// std::cerr << "Invalid argument type for trigger command." << std::endl; -// return; -// } -// -//#pragma endregion -// if (args[0].toString() == "write" && args.size() >= 3) { -// bool result = _serviceManager->_triggerManager->sendFinsMsg( -// QString("write_" + args[1].toString() + "_" -// + args[2].toString() -// )); -// if (!result) -// std::cerr << "Failed to send write command." << std::endl; -// else -// std::cout << "Write command sent successfully." << std::endl; -// return; -// } -// else if (args[0].toString() == "read" && args.size() >= 2) { -// QVariant result = _serviceManager->_triggerManager->read(args[1].toInt()); -// if (result.isValid()) { -// std::cout << "Read command result: " << result.toString().toStdString() << std::endl; -// } -// else { -// std::cerr << "Failed to read data." << std::endl; -// } -// } -// } -// catch(const std::exception& e) { -// std::cerr << "Error in trigger command: " << e.what() << std::endl; -// } -// catch (...) { -// std::cerr << "Unknown error occurred in trigger command." << std::endl; -// } -// } -// void evaluate(std::vector&args) { -//#pragma region 处理错误 -// //if() -//#pragma endregion -// -// } -#pragma endregion bool cliCommand(const QString& command) { auto strList = command.split("#"); if (strList[0] == "fins") { @@ -140,9 +69,9 @@ public: QStringList basicTriggerPresetGenerate(int& triggerAddress) { QString triggerAddressStr = QString::number(triggerAddress); return { - "fins#write_short_"+ triggerAddressStr +"_1", + "fins#write_short_D"+ triggerAddressStr +"_1", "waitMs#500", - "fins#write_short_" + triggerAddressStr + "_0", + "fins#write_short_D" + triggerAddressStr + "_0", }; } private: diff --git a/src/core/fuck-u-code-windows-amd64.exe b/src/fuck-u-code-windows-amd64.exe similarity index 100% rename from src/core/fuck-u-code-windows-amd64.exe rename to src/fuck-u-code-windows-amd64.exe diff --git a/src/launcher/CMakeLists.txt b/src/launcher/CMakeLists.txt index 13eb6a9..09c1cb7 100644 --- a/src/launcher/CMakeLists.txt +++ b/src/launcher/CMakeLists.txt @@ -2,7 +2,7 @@ string(TIMESTAMP RUN_TIME) message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) STRING(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) -set(DLL_NAMES "halcon" "opencv" "sqlite" "handdleAI""myTools" "mvs" "3DAI" "python" "spdLog" "breakpad") +set(DLL_NAMES "halcon" "opencv""myTools" "mvs" "spdLog" "breakpad" "hwinfo") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) @@ -14,6 +14,7 @@ message(" ENV_TARGET : " ${ENV_TARGET} ) include_directories( ${ENV_INCLUDE} ${PROJECT_ROOT_PATH}/lib/${CMAKE_BUILD_TYPE} + ${CMAKE_CURRENT_SOURCE_DIR}/hardwareInfo ${CMAKE_CURRENT_SOURCE_DIR}/logger ${CMAKE_CURRENT_SOURCE_DIR}/GUI ${CMAKE_CURRENT_SOURCE_DIR}/appConfig diff --git a/src/launcher/GUI/front/pages/configSettingWidget.h b/src/launcher/GUI/front/pages/configSettingWidget.h index a3ed452..7967b73 100644 --- a/src/launcher/GUI/front/pages/configSettingWidget.h +++ b/src/launcher/GUI/front/pages/configSettingWidget.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -17,7 +16,9 @@ #include #include #include +#include #include "git_version.h" +#include /**************格式****************/ //... //{ @@ -70,31 +71,23 @@ public: return "error"; } }; - QVBoxLayout* Layout; + QVBoxLayout* m_layout = new QVBoxLayout(this); QHBoxLayout* btnLayout; std::vectorbtns; QLabel* icon, * Title; - QStackedWidget* stackedWidgets; int currentPageIndex = 0; - configSettingWidget() - { + configSettingWidget(appConfig* _configIn):_config(_configIn){ QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); QFont font("微软雅黑", 24, QFont::Bold); QFont font2("微软雅黑", 8, QFont::Bold); - stackedWidgets = new QStackedWidget(); - stackedWidgets->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - stackedWidgets->setMaximumSize(9999, 9999); - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setMaximumSize(9999, 9999); this->setObjectName("configSettingWidget"); //this->setStyleSheet(QString("QWidget {background-color: rgb(%1)}").arg(sColor_Gold)); //this->showMaximized(); - Layout = new QVBoxLayout(this); - Layout->setContentsMargins(0, 0, 0, 0); - Layout->setAlignment(Qt::AlignLeft|Qt::AlignTop); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setAlignment(Qt::AlignLeft|Qt::AlignTop); QHBoxLayout* titleLayout = new QHBoxLayout(); Title = new QLabel(u8"设置"); @@ -111,25 +104,25 @@ public: titleLayout->addWidget(Title); titleLayout->addWidget(versionShow); - titleLayout->setAlignment(Qt::AlignBottom); - Layout->addLayout(titleLayout); - - /*btnLayout = new QHBoxLayout(); - btnLayout->setContentsMargins(0, 0, 0, 0); - btnLayout->setAlignment(Qt::AlignLeft); + titleLayout->setAlignment(Qt::AlignLeft | Qt::AlignBottom); + m_layout->addLayout(titleLayout); - Layout->addLayout(btnLayout); - - addConfigWidget(u8"通用设置",".//config//basicSetting.json"); - addConfigWidget(u8"检测设置",""); - addConfigWidget(u8"通讯设置",".//config//communicateConfig"); - addConfigWidget(u8"算法设置",""); - addConfigWidget(u8"运动设置",""); - addConfigWidget(u8"模型设置",""); - btns[0]->pressed(); + fancyButtonText* showConsoleBtn = new fancyButtonText(100, 30, "显示控制台", ""); + m_layout->addWidget(showConsoleBtn); + connect(showConsoleBtn, &QPushButton::clicked, [=]() { + ShowWindow(_config->consoleHandle, SW_SHOW); + }); + + fancyButtonText* hideConsoleBtn = new fancyButtonText(100, 30, "隐藏控制台", ""); + m_layout->addWidget(hideConsoleBtn); + connect(hideConsoleBtn, &QPushButton::clicked, [=]() { + ShowWindow(_config->consoleHandle, SW_HIDE); + }); + + m_layout->addWidget(&_hardwareInfoWidget); - Layout->addWidget(stackedWidgets);*/ } +#if 0 //格式检查 bool formatPolicyCompare(formatPolicy _formatPolicy,QString compareStr,QString& textOut,QString &colorOut) { @@ -430,13 +423,12 @@ public: std::string sss = path.toStdString(); saveJsonFromPath(sss, json); } +#endif protected: - void resizeEvent(QResizeEvent* event) override { - Q_UNUSED(event); - //QTimer::singleShot(0, this, &configSettingWidget::updateLayout); - } private: + appConfig* _config; + hardwareInfoWidget _hardwareInfoWidget; std::vector> privateJsondatas;//路径与数据 std::vector> privateWidgets;//路径与数据 std::vectorjsonLayouts; diff --git a/src/launcher/GUI/front/pages/historyWidget.h b/src/launcher/GUI/front/pages/historyWidget.h index 07d1313..02ac703 100644 --- a/src/launcher/GUI/front/pages/historyWidget.h +++ b/src/launcher/GUI/front/pages/historyWidget.h @@ -26,8 +26,7 @@ public: historyShowListWidget _historyShowListWidget; QLabel* imgPosTip = new QLabel(); std::unordered_map namePairPixmap;//型号对应图片; - historyWidget() - { + historyWidget() { QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); QFont font("微软雅黑", 24, QFont::Bold); diff --git a/src/launcher/GUI/front/pages/sqlControlWidget.h b/src/launcher/GUI/front/pages/sqlControlWidget.h index 9dafbc8..56654b8 100644 --- a/src/launcher/GUI/front/pages/sqlControlWidget.h +++ b/src/launcher/GUI/front/pages/sqlControlWidget.h @@ -9,12 +9,14 @@ #include #include #include +#include class sqliteReader : public QWidget { Q_OBJECT public: sqliteReader() { + db = new SQLiteDB(globalDatabasePth); QFont font("微软雅黑", 12, QFont::Bold); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -32,7 +34,10 @@ public: tableSelectComboBox->setFixedWidth(150); vLayout->addWidget(tableSelectComboBox); connect(tableSelectComboBox, QOverload::of(&QComboBox::currentIndexChanged), - this, [=]() {switchWidget(tableSelectComboBox->currentText()); }); + this, [=]() { + if(tableSelectComboBox->currentText() != "") + switchWidget(tableSelectComboBox->currentText()); + }); refreshBtn->setFont(font); refreshBtn->setPalette(palette); @@ -56,12 +61,11 @@ public: //1-2 layout->addWidget(tableWidget); } - appConfig* _config; //QTableView* view = new QTableView; void refreshTable() { tableSelectComboBox->clear(); - auto tables = _config->g_db->getTables(); + auto tables = db->getTables(); for (int i = tables.size() - 1; i > 0 ; i--){ if (!tables[i].contains("set")) tableSelectComboBox->addItem(tables[i]); @@ -69,7 +73,7 @@ public: } void switchWidget(QString tableName) { QSqlQueryModel* model = new QSqlQueryModel; - model->setQuery("SELECT * from \"" + tableName + "\""); + model->setQuery("SELECT * from \"" + tableName + "\"",db->db); if (model->lastError().isValid()) { qDebug() << "查询失败:" << model->lastError().text(); @@ -84,7 +88,7 @@ public: .arg(SN); QSqlQueryModel* model = new QSqlQueryModel; - model->setQuery(queryStr); + model->setQuery(queryStr,db->db); if (model->lastError().isValid()) { qDebug() << "SN查询失败:" << model->lastError().text(); @@ -110,9 +114,9 @@ public: // 导出数据 bool success = false; - if (_config && _config->g_db) { + if (db) { std::mutex mutex; - success = _config->g_db->exportTableToCSV(tableName, filePath, mutex); + success = db->exportTableToCSV(tableName, filePath, mutex); } // 提示导出结果 @@ -124,6 +128,8 @@ public: } private: + SQLiteDB *db; + QString connectionName = ""; QComboBox* tableSelectComboBox = new QComboBox(); QVBoxLayout* layout = new QVBoxLayout(this); QTableView* tableWidget = new QTableView(); @@ -149,7 +155,6 @@ public: QLabel* disconnnectedLabel = new QLabel("服务已离线"); sqlControlWidget(appConfig* _configIN){ - _sqliteReader._config = _configIN; this->setObjectName("sqlControlWidget"); this->setStyleSheet(R"( QWidget#sqlControlWidget { diff --git a/src/launcher/GUI/front/pages/summary_data_page.h b/src/launcher/GUI/front/pages/summary_data_page.h index 34d1d62..e10483a 100644 --- a/src/launcher/GUI/front/pages/summary_data_page.h +++ b/src/launcher/GUI/front/pages/summary_data_page.h @@ -6,298 +6,7 @@ #include #include #include -#include -#include - -class WaveFormWidget : public QWidget { - Q_OBJECT -public: - WaveFormWidget(nlohmann::ordered_json& json, QWidget* parent = nullptr) - : QWidget(parent), m_json(json), - m_mainLayout(new QVBoxLayout(this)), - m_title(new QLabel(this)), - m_plot(new QCustomPlot(this)) - { - QString title = QString::fromStdString(json.value("key", "默认标题")); - m_limitHigh = json.value("limitHigh", 100.0); - m_limitLow = json.value("limitLow", 0.0); - m_maxPoints = json.value("maxPoints", 50); - - QFont font("微软雅黑", 24, QFont::Bold); - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - - setObjectName("WaveFormWidget"); - setStyleSheet("QWidget#WaveFormWidget {background-color: rgb(100,100,255);}"); - m_title->setText(title); - m_title->setFixedHeight(60); - m_title->setAlignment(Qt::AlignHCenter); - m_title->setPalette(palette); - m_title->setFont(font); - - m_mainLayout->addWidget(m_title); - m_mainLayout->addWidget(m_plot); - - m_plot->setBackground(Qt::transparent); - - // 主蓝色曲线 - m_plot->addGraph(); - m_plot->graph(0)->setPen(QPen(QColor(0,191,255), 3)); - m_plot->graph(0)->setScatterStyle(QCPScatterStyle::ssNone); - - // 新增红色点图层 - m_plot->addGraph(); - m_plot->graph(1)->setLineStyle(QCPGraph::lsNone); - m_plot->graph(1)->setScatterStyle( - QCPScatterStyle(QCPScatterStyle::ssDisc, QPen(Qt::red), QBrush(Qt::red), 5) - ); - m_plot->xAxis->setBasePen(QPen(Qt::white, 2)); // 坐标轴线 - m_plot->yAxis->setBasePen(QPen(Qt::white, 2)); - - m_plot->xAxis->setTickPen(QPen(Qt::white)); // 刻度线 - m_plot->yAxis->setTickPen(QPen(Qt::white)); - - m_plot->xAxis->setSubTickPen(QPen(Qt::white)); // 次刻度 - m_plot->yAxis->setSubTickPen(QPen(Qt::white)); - - m_plot->xAxis->setTickLabelColor(Qt::white); // 数字标签 - m_plot->yAxis->setTickLabelColor(Qt::white); - - m_plot->xAxis->setLabelColor(Qt::white); // "时间" / "数值" 文字 - m_plot->yAxis->setLabelColor(Qt::white); - - - - // 鼠标追踪 - m_tracer = new QCPItemTracer(m_plot); - m_tracer->setGraph(m_plot->graph(0)); // 追踪蓝色曲线 - m_tracer->setStyle(QCPItemTracer::tsCircle); - m_tracer->setPen(QPen(Qt::yellow)); - m_tracer->setBrush(Qt::yellow); - m_tracer->setSize(7); - m_tracer->setVisible(false); // 默认隐藏 - - // 文本提示 - m_tracerText = new QCPItemText(m_plot); - m_tracerText->setColor(Qt::white); // 文字颜色 - m_tracerText->setFont(QFont("微软雅黑", 10, QFont::Bold)); - m_tracerText->position->setType(QCPItemPosition::ptPlotCoords); - m_tracerText->setBrush(QBrush(QColor(0, 0, 0, 150))); // 半透明背景 - m_tracerText->setPadding(QMargins(5, 2, 5, 2)); // 留点内边距 - m_tracerText->setVisible(false); - - // 绑定鼠标移动事件 - connect(m_plot, &QCustomPlot::mouseMove, this, &WaveFormWidget::onMouseMoveInPlot); - if (title.contains("对齐度")) { - auto fixedTicker = QSharedPointer(new QCPAxisTickerFixed); - fixedTicker->setTickStep(0.1); - fixedTicker->setScaleStrategy(QCPAxisTickerFixed::ssNone); // 不自动放大 - m_plot->yAxis->setTicker(fixedTicker); - m_plot->yAxis->setRange(-0.2,0.8); - } - else - updateYrange(m_limitLow, m_limitHigh); - - - addLimitLines(m_limitHigh, m_limitLow); - } - void updateYrange(double low, double high) { - m_plot->yAxis->setRange(qMax(0.0, m_limitLow - (m_limitHigh - m_limitLow)), m_limitHigh + 2); - } - void appendData(double value) { - QMutexLocker locker(&mutex); - m_xData.append(m_timeCounter); - m_yData.append(value); - - // 超限 - if (value > m_limitHigh || value < m_limitLow) { - m_xOverLimit.append(m_timeCounter); - m_yOverLimit.append(value); - - //auto* textItem = new QCPItemText(m_plot); - //textItem->setPositionAlignment(Qt::AlignLeft | Qt::AlignBottom); - //textItem->position->setType(QCPItemPosition::ptPlotCoords); - //textItem->position->setCoords(m_timeCounter, value); - //textItem->setText(QString::number(value, 'f', 2)); - //textItem->setColor(Qt::yellow); - //textItem->setFont(QFont("微软雅黑", 8,QFont::Bold)); - //m_textItems.append(textItem); - } - - ++m_timeCounter; - - // 保持窗口大小 - if (m_xData.size() > m_maxPoints) { - m_xData.removeFirst(); - m_yData.removeFirst(); - } - if (m_xOverLimit.size() > m_maxPoints) { - m_xOverLimit.removeFirst(); - m_yOverLimit.removeFirst(); - } - - // 清理超出窗口范围的文本 - while (!m_textItems.isEmpty() && m_textItems.first()->position->key() < m_timeCounter - m_maxPoints) { - m_plot->removeItem(m_textItems.first()); - m_textItems.removeFirst(); - } - - m_plot->graph(0)->setData(m_xData, m_yData); - m_plot->graph(1)->setData(m_xOverLimit, m_yOverLimit); - m_plot->xAxis->setRange(qMax(0.0, m_timeCounter - m_maxPoints), m_timeCounter); - m_plot->replot(); - } - - -protected: - void contextMenuEvent(QContextMenuEvent* event) override { - QMenu menu(this); - menu.addAction("编辑参数", this, &WaveFormWidget::editJsonParameters); - menu.exec(event->globalPos()); - } - - void leaveEvent(QEvent* event) override { - if (m_tracer) m_tracer->setVisible(false); - if (m_tracerText) m_tracerText->setVisible(false); - m_plot->replot(); - QWidget::leaveEvent(event); - } -#if switchToTongYongUi == 1 - void paintEvent(QPaintEvent* event) override { - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - int radius = 10; // 圆角半径 - QRect r = rect(); - - // 填充圆角背景 - painter.setBrush(QColor(50, 55, 60)); - painter.setPen(Qt::NoPen); - painter.drawRoundedRect(r, radius, radius); - } -#endif -private slots: - void editJsonParameters() { - JsonParamTableEditor* dlg = new JsonParamTableEditor(this); - dlg->setJsonObject(m_json); - dlg->setAttribute(Qt::WA_DeleteOnClose); - connect(dlg, &JsonParamTableEditor::jsonAccepted, [this](const nlohmann::json& result) { - m_json = result; - applyJsonParams(); - }); - dlg->show(); - } - void onMouseMoveInPlot(QMouseEvent* event) { - double x = m_plot->xAxis->pixelToCoord(event->pos().x()); - if (!m_xData.isEmpty()) { - double y = findNearestYValue(x); - - m_tracer->setGraphKey(x); - m_tracer->updatePosition(); - m_tracer->setVisible(true); - - m_tracerText->setText(QString("%1\n值:%2") - .arg(static_cast(std::round(x))) - .arg(y, 0, 'f', 2)); - m_tracerText->setVisible(true); - m_tracerText->setTextAlignment(Qt::AlignLeft); - - // 判断左右边显示气泡 - int mouseX = event->pos().x(); - int mouseY = event->pos().y(); - int plotWidth = m_plot->width(); - int plotHeight = m_plot->height(); - - Qt::Alignment hAlign = (mouseX < plotWidth / 2) ? Qt::AlignLeft : Qt::AlignRight; - Qt::Alignment vAlign = (mouseY < plotHeight / 2) ? Qt::AlignTop : Qt::AlignBottom; - - m_tracerText->setPositionAlignment(hAlign | vAlign); - - m_tracerText->position->setCoords(x, y); - m_plot->replot(); - } - } - -private: - void applyJsonParams() { - QMutexLocker locker(&mutex); // 确保线程安全 - m_maxPoints = m_json.value("maxPoints", m_maxPoints); - m_limitHigh = m_json.value("limitHigh", m_limitHigh); - m_limitLow = m_json.value("limitLow", m_limitLow); - - m_title->setText(QString::fromStdString(m_json.value("key", m_title->text().toStdString()))); - m_plot->clearItems(); - addLimitLines(m_limitHigh, m_limitLow); - - // 更新坐标范围 - updateYrange(m_limitLow, m_limitHigh); - - // 清空超限数据 - m_xOverLimit.clear(); - m_yOverLimit.clear(); - - m_plot->replot(); - } - - // 简单线性插值(或者最近点) - double interpolateYValue(double x) { - for (int i = 1; i < m_xData.size(); ++i) { - if (m_xData[i] >= x) { - double x0 = m_xData[i - 1], y0 = m_yData[i - 1]; - double x1 = m_xData[i], y1 = m_yData[i]; - if (x1 == x0) return y0; - return y0 + (y1 - y0) * (x - x0) / (x1 - x0); - } - } - return m_yData.last(); // 超出范围 - } - double findNearestYValue(double x) { - if (m_xData.isEmpty()) - return 0; - - int nearestIndex = 0; - double minDist = std::abs(m_xData[0] - x); - - for (int i = 1; i < m_xData.size(); ++i) { - double dist = std::abs(m_xData[i] - x); - if (dist < minDist) { - minDist = dist; - nearestIndex = i; - } - } - - return m_yData[nearestIndex]; - } - - void addLimitLines(double high, double low) { - auto* line1 = new QCPItemStraightLine(m_plot); - line1->setPen(QPen(Qt::green, 1, Qt::SolidLine)); - line1->point1->setCoords(0, high); - line1->point2->setCoords(1, high); - - auto* line2 = new QCPItemStraightLine(m_plot); - line2->setPen(QPen(Qt::green, 1, Qt::SolidLine)); - line2->point1->setCoords(0, low); - line2->point2->setCoords(1, low); - } - - nlohmann::ordered_json& m_json; - QVBoxLayout* m_mainLayout; - QLabel* m_title; - QCustomPlot* m_plot; - QList m_textItems; - QVector m_xData, m_yData; - QVector m_xOverLimit, m_yOverLimit; // 新增用于红色点 - int m_maxPoints = 50; - double m_timeCounter = 0; - double m_limitHigh = -1, m_limitLow = 2; - QCPItemTracer* m_tracer = nullptr; - QCPItemText* m_tracerText = nullptr; -private: - QMutex mutex; -}; - - +#include class SummuaryDataPage :public QWidget { Q_OBJECT public: @@ -314,7 +23,6 @@ public: QFont font2("微软雅黑", 108, QFont::Bold); this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setMaximumSize(9999, 9999); this->setObjectName(u8"生产数据采集"); m_layout->setContentsMargins(0, 0, 0, 0); @@ -379,8 +87,10 @@ public: QString name = QString::fromStdString(json.at("key")); int x = json.at("x"); int y = json.at("y"); + m_waveFormMap[pageName + "#" + name] = new WaveFormWidget(json); layoutList[page]->addWidget(m_waveFormMap[pageName + "#" + name], y, x, 1, 1); + } void addData(QString name, double data) { if(m_waveFormMap[name] == nullptr) { diff --git a/src/launcher/GUI/mainwindow.cpp b/src/launcher/GUI/mainwindow.cpp index ec62954..686154e 100644 --- a/src/launcher/GUI/mainwindow.cpp +++ b/src/launcher/GUI/mainwindow.cpp @@ -249,7 +249,7 @@ void MainWindow::leftBarInit(){ //registerPageBar(":/icon/icon/cycleButton.png", u8"手动检测", _manualDetWidget); //历史图片 - _historyWidget = new historyWidget(); + //_historyWidget = new historyWidget(); //registerPageBar(":/icon/icon/history.png", u8"历史图片", _historyWidget); //SQL @@ -260,7 +260,7 @@ void MainWindow::leftBarInit(){ //registerPageBar(":/icon/icon/sql.png", u8"SQL可视化", _pluginManagerWidget); // //配置页面 - _configSettingWidget = new configSettingWidget(); + _configSettingWidget = new configSettingWidget(config); registerPageBar(":/icon/icon/setting.png", u8"配置设置", _configSettingWidget); for (int index = 0; index < pageBtns.size(); index++) { @@ -274,5 +274,5 @@ void MainWindow::leftBarInit(){ pageBtns[0]->click(); QObject::connect(_displayWidget, &displayWidget::changeStackWidget, this, &MainWindow::switchStackWidget); - QObject::connect(_displayWidget, &displayWidget::historyClickSignal, _historyWidget, &historyWidget::widgetJumpWithPath); +// QObject::connect(_displayWidget, &displayWidget::historyClickSignal, _historyWidget, &historyWidget::widgetJumpWithPath); } \ No newline at end of file diff --git a/src/launcher/GUI/mainwindow.h b/src/launcher/GUI/mainwindow.h index bd4b71c..57d4d72 100644 --- a/src/launcher/GUI/mainwindow.h +++ b/src/launcher/GUI/mainwindow.h @@ -27,11 +27,10 @@ #include "front/pages/manualDetWidget.h" #include "front/pages/historyWidget.h" #include -#include -#include #include "front/pages/pluginManagerWidget.hpp" #include "front/pages/summary_data_page.h" #include +#include 8 #pragma execution_character_set("utf-8") QT_BEGIN_NAMESPACE diff --git a/src/launcher/GUI/simpleTools/eulerCoordinateAlgo.h b/src/launcher/GUI/simpleTools/eulerCoordinateAlgo.h deleted file mode 100644 index e61cf4c..0000000 --- a/src/launcher/GUI/simpleTools/eulerCoordinateAlgo.h +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -static double degToRad(double deg) { - return deg * M_PI / 180.0; -} -static double radToDeg(double deg) { - return deg / M_PI * 180.0; -} -static cv::Vec3d radToDeg(cv::Vec3d rad) { - rad[0] /= M_PI / 180.0; - rad[1] /= M_PI / 180.0; - rad[2] /= M_PI / 180.0; - return rad; -} -// 计算旋转矩阵 -static cv::Mat get_rotation_matrix(double alpha, double beta, double gamma) { - // Roll (x-axis rotation) - cv::Mat R_x = (cv::Mat_(3, 3) << - 1, 0, 0, - 0, cos(alpha), -sin(alpha), - 0, sin(alpha), cos(alpha)); - - // Pitch (y-axis rotation) - cv::Mat R_y = (cv::Mat_(3, 3) << - cos(beta), 0, sin(beta), - 0, 1, 0, - -sin(beta), 0, cos(beta)); - - // Yaw (z-axis rotation) - cv::Mat R_z = (cv::Mat_(3, 3) << - cos(gamma), -sin(gamma), 0, - sin(gamma), cos(gamma), 0, - 0, 0, 1); - - // Combined rotation matrix - return R_z * R_y * R_x; -} - -// 主函数 -static cv::Mat transform_coordinates(cv::Mat coords, cv::Vec3d radInput1, cv::Vec3d radInput2) { - // 原始旋转矩阵 - cv::Mat R_old = get_rotation_matrix(radInput1[0], radInput1[1], radInput1[2]); - // 新的旋转矩阵 - cv::Mat R_new = get_rotation_matrix(radInput2[0], radInput2[1], radInput2[2]); - // 计算新坐标 - cv::Mat new_coords = R_new * R_old.inv() * coords; - return new_coords; -} - -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/simpleTools/fileManager.cpp b/src/launcher/GUI/simpleTools/fileManager.cpp deleted file mode 100644 index 43f726a..0000000 --- a/src/launcher/GUI/simpleTools/fileManager.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -bool fileManager::setFileReadOnly(const std::string& filePath, bool readOnly) { - DWORD attributes = GetFileAttributes(filePath.c_str()); - if (attributes == INVALID_FILE_ATTRIBUTES) { - std::cerr << "Error getting file attributes: " << GetLastError() << std::endl; - return false; - } - - if (readOnly) { - attributes |= FILE_ATTRIBUTE_READONLY; - } - else { - attributes &= ~FILE_ATTRIBUTE_READONLY; - } - - if (!SetFileAttributes(filePath.c_str(), attributes)) { - std::cerr << "Error setting file attributes: " << GetLastError() << std::endl; - return false; - } - - return true; -} \ No newline at end of file diff --git a/src/launcher/GUI/simpleTools/fileManager.h b/src/launcher/GUI/simpleTools/fileManager.h deleted file mode 100644 index aa7cd08..0000000 --- a/src/launcher/GUI/simpleTools/fileManager.h +++ /dev/null @@ -1,386 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class fileManager -{ -public: - - /// - /// 获取所有文件夹 - /// - /// - /// - static std::vector getAllDirs(const QString& folderPath) - { - std::vector foldersVec; - QDir folderDir(folderPath); - if (!folderDir.exists()) { - return foldersVec; - } - - QStringList folders = folderDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - - for (const QString& folder : folders) { - foldersVec.push_back(folderPath.toStdString()+"//" + folder.toStdString()); - } - return foldersVec; - } - /// - /// 获取文件夹下格式的文件,以vector返回 - /// - /// - /// - /// - static void getAllFiles(std::string path, std::vector& files, std::string format, int targetDepth = INT_MAX, int depth = 0) - { - if (depth >= targetDepth) - return; - intptr_t hFile = 0; - struct _finddata_t fileinfo; - std::string p; - if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) - { - do - { - if ((fileinfo.attrib & _A_SUBDIR)) - { - if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) - { - files.push_back(p.assign(path).append("\\").append(fileinfo.name)); - depth++; - getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format, targetDepth ,depth); - } - } - else - { - files.push_back(p.assign(path).append("\\").append(fileinfo.name)); - } - } while (_findnext(hFile, &fileinfo) == 0); - _findclose(hFile); - } - } - /// - /// 获取文件夹下的图片,以vector返回 - /// - /// - /// - /// - static void getAllImages(std::string path, std::vector& files, std::string format, int targetDepth = INT_MAX, int depth = 0) - { - if (depth >= targetDepth) - return; - intptr_t hFile = 0; - struct _finddata_t fileinfo; - std::string p; - if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) - { - do - { - if ((fileinfo.attrib & _A_SUBDIR)) - { - if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) - { - std::string filePath = p.assign(path).append("\\").append(fileinfo.name); - if (fileManager::isImageFile(filePath) == true) - files.push_back(filePath); - depth++; - getAllImages(filePath, files, format, targetDepth, depth); - } - } - else - { - std::string filePath = p.assign(path).append("\\").append(fileinfo.name); - if (fileManager::isImageFile(filePath) == true) - files.push_back(filePath); - } - } while (_findnext(hFile, &fileinfo) == 0); - _findclose(hFile); - } - } - /// - /// 检查磁盘剩余空间,以GB为单位返回 - /// - /// example"E://""E://111/222"支持文件夹或者磁盘路径 - /// - static int getDriveFreeSpaceAsGb(const QString& folderPath) { - QStorageInfo storageInfo(folderPath); - - if (storageInfo.isValid() && storageInfo.isReady()) { - return storageInfo.bytesAvailable() / 1073741824; - } - - return -1; // Indicate failure to retrieve disk space - } - /// - /// 检查磁盘剩余空间,以Mb为单位返回 - /// - /// example"E://""E://111/222"支持文件夹或者磁盘路径 - /// - static int getDriveFreeSpaceAsMb(const QString& folderPath) { - QStorageInfo storageInfo(folderPath); - - if (storageInfo.isValid() && storageInfo.isReady()) { - return storageInfo.bytesAvailable() / 1048576; - } - - return -1; // Indicate failure to retrieve disk space - } - /// - /// 返回最老创建时间文件夹名 - /// - /// - /// - static QString getOldestDir(const QString& folderPath) - { - std::string oldestDir; - QDateTime oldestTime; - std::vector files= getAllDirs(folderPath); - for (auto file : files) - { - QFileInfo fileInfo(QString::fromStdString(folderPath.toStdString() + "//" + file)); - QDateTime fileTime = fileInfo.created(); - QString str = fileInfo.created().toString(); - std::cout << "Current date and time: " << str.toStdString() << std::endl; - if (oldestTime.isNull() || fileTime < oldestTime) - { - oldestTime = fileTime; - oldestDir = file; - } - } - return QString::fromStdString(oldestDir); - } - /// - /// 删除最老创建时间文件夹 - /// - /// - /// - static bool deleteOldestDir(const QString& folderPath) - { - QString oldestDir =getOldestDir(folderPath); - if (oldestDir.isEmpty()) - return false; - oldestDir= folderPath+ "//" + oldestDir; - QDir dir(oldestDir); - dir.removeRecursively(); - return true; - } - /// - /// 删除最老子文件夹 - /// - /// - /// - static bool deleteOldestSonDir(const QString& folderPath) - { - QString oldestDir = getOldestDir(folderPath); - if (oldestDir.isEmpty()) - return false; - oldestDir = folderPath + "//" + oldestDir; - deleteOldestDir(oldestDir); - if (getAllDirs(oldestDir).size() == 0)//删除后文件夹为空,删除父文件夹 - { - QDir dir(oldestDir); - dir.removeRecursively(); - } - return true; - } - /// - /// 删除几天前的所有文件夹 - /// - /// - /// - /// - static bool deleteDirBeforeDays(const QString& folderPath, int day) - { - std::vector dirs=getAllDirs(folderPath); - for (auto& dir : dirs) - { - QFileInfo fileInfo(QString::fromStdString(dir)); - QDateTime fileTime = fileInfo.created(); - QDateTime nowTime = QDateTime::currentDateTime(); - std::string result = fileTime.toString("yyyy-MM-dd").toStdString(); - int dayBefore = fileTime.daysTo(nowTime); - if (dayBefore > day) - { - QDir dir(QString::fromStdString(dir)); - dir.removeRecursively(); - } - } - return true; - } - //去除重复分割符 - static QString normalizePathSeparators(const QString& path) { - QString normalizedPath = path; - - // Replace backslashes with forward slashes - normalizedPath.replace('\\', '/'); - - // Remove consecutive forward slashes - QString doubleSlash = "//"; - while (normalizedPath.contains(doubleSlash)) { - normalizedPath.replace(doubleSlash, "/"); - } - - return normalizedPath; - } - - static bool isImageFile(const std::string& filename) { - const std::string imageExtensions[] = { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp" }; - - std::string lowerFilename = filename; - std::transform(lowerFilename.begin(), lowerFilename.end(), lowerFilename.begin(), [](unsigned char c) { return std::tolower(c); }); - - for (const std::string& ext : imageExtensions) { - if (lowerFilename.size() >= ext.size() && - lowerFilename.compare(lowerFilename.size() - ext.size(), ext.size(), ext) == 0) { - return true; - } - } - - return false; - } - static std::string getFileName(std::string path) - { - if (path.find("\\") != std::string::npos) - return path.substr(path.find_last_of("\\") + 1, path.find_last_of(".") - path.find_last_of("\\") - 1); - return path.substr(path.find_last_of("/") + 1, path.find_last_of(".") - path.find_last_of("/") - 1); - } - static QString getFileName(const QString& path) { - int lastSlashIndex = path.lastIndexOf('/'); - if (lastSlashIndex == -1) { - lastSlashIndex = path.lastIndexOf('\\'); - } - - int lastDotIndex = path.lastIndexOf('.'); - - if (lastDotIndex == -1 || lastDotIndex < lastSlashIndex) { - return path.mid(lastSlashIndex + 1); - } - else { - return path.mid(lastSlashIndex + 1, lastDotIndex - lastSlashIndex - 1); - } - } - //统一地址分隔符 - static QString normalizePathStr(const QString& address, QChar targetSeparator = '/') { - QString normalizedAddress = address; - for (int i = 0; i < normalizedAddress.size(); ++i) { - if (normalizedAddress[i] == '\\' || normalizedAddress[i] == '/') { - normalizedAddress[i] = targetSeparator; - } - } - return normalizedAddress; - } - //统一地址分隔符 - static std::string normalizePathStr(const std::string& address, char targetSeparator = '/') { - std::string normalizedAddress = address; - for (char& ch : normalizedAddress) { - if (ch == '\\' || ch == '/') { - ch = targetSeparator; - } - } - return normalizedAddress; - } - static void createDirectoryIfNotExists(const std::string& path) { - // 检查路径是否存在 - if (!std::filesystem::exists(path)) { - // 创建路径 - - std::filesystem::create_directories(path); - //std::cout << "已创建文件夹: " << path << std::endl; - } - else {/* - std::cout << "文件夹已存在: " << path << std::endl;*/ - } - } - static bool setFileReadOnly(const std::string& filePath, bool readOnly); -}; -/// -/// 自动删除文件夹,支持按日期删除,按磁盘剩余容量删除,或者两者都是,请在主线程声明qtimer -/// -class autoDelete : public QThread -{ - Q_OBJECT -public: - enum clearMode - { - dayBefore, - sizeOver, - sizeOverOrDayBefore, - }; - /// - /// 构造函数 - /// - /// 文件夹路径 - /// 删除几天前的,磁盘剩余容量小于多少,两者都是 - /// 检测间隔如果只检测日期建议设大一点,如果只检测磁盘容量建议设小一点,默认十分钟 - autoDelete(std::vector pathVec,clearMode mode,int sec) - { - for (auto& path : pathVec) - detPathVec.push_back(QString::fromStdString(path)); - detMode = mode; - threadInterval = sec; - this->start(); - } - ~autoDelete() - { - runFlag = false; - } - void run() override - { - while(runFlag) - { - exacute(); - QThread::sleep(threadInterval); - } - } - void exacute() - { - for(auto & detPath : detPathVec) - { - switch (detMode) - { - case dayBefore://删除几天前的 - fileManager::deleteDirBeforeDays(detPath, daySet); - break; - case sizeOver://磁盘剩余容量小于多少 - if (fileManager::getDriveFreeSpaceAsGb(detPath) < sizeSet) - fileManager::deleteOldestSonDir(detPath);//删除最老的文件夹 - break; - case sizeOverOrDayBefore://两者都是 - if (fileManager::getDriveFreeSpaceAsGb(detPath) < sizeSet)//磁盘剩余容量小于多少 - fileManager::deleteOldestDir(detPath);//删除最老的文件夹 - fileManager::deleteDirBeforeDays(detPath, daySet);//同时删除几天前的 - break; - default: - qDebug() << "none mode det"; - break; - } - } - } - void setDay(int day) - { - daySet = day; - } - void setSize(int size) - { - sizeSet = size; - } -private: - std::vector detPathVec; - clearMode detMode; - int daySet = 30;//天 - int sizeSet = 100;//GB - int threadInterval = 0;//sec - bool runFlag = true; -}; - -#pragma once diff --git a/src/launcher/GUI/simpleTools/lightSource.hpp b/src/launcher/GUI/simpleTools/lightSource.hpp deleted file mode 100644 index 6a54b52..0000000 --- a/src/launcher/GUI/simpleTools/lightSource.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#include -enum lightSourceChannel -{ - AChannel, BChannel, CChannel, DChannel -}; -class lightSource -{ -public: - QSerialPort* serialPort = new QSerialPort(); - lightSource(std::string comName, int baudRate, std::string initStr) - { - serialPort->close(); - serialPort->setPortName(QString::fromStdString(comName)); - serialPort->open(QIODevice::ReadWrite); - if (serialPort->isOpen() != true) - { - DisableComPort(comName.c_str()); - _sleep(1000); - EnableComPort(comName.c_str()); - serialPort->open(QIODevice::ReadWrite); - if (serialPort->isOpen() != true) - { - qDebug() << comName.c_str() << "open failure!!"; - return; - } - } - serialPort->setBaudRate(baudRate); - serialPort->setDataBits(QSerialPort::Data8); - serialPort->setParity(QSerialPort::NoParity); - serialPort->setStopBits(QSerialPort::OneStop); - serialPort->setFlowControl(QSerialPort::NoFlowControl); - serialPort->write(initStr.c_str()); - serialPort->waitForBytesWritten(); - - } - void setValue(lightSourceChannel channelIn,unsigned char value) - { - std::string controlStr; - switch (channelIn) - { - case lightSourceChannel::AChannel: - controlStr = "SA0"; - break; - case lightSourceChannel::BChannel: - controlStr = "SB0"; - break; - case lightSourceChannel::CChannel: - controlStr = "SC0"; - break; - case lightSourceChannel::DChannel: - controlStr = "SD0"; - break; - } - std::string valueStr = std::to_string(value); - if (valueStr.length() < 3) - for (int i = 0; i < 3 - valueStr.length(); i++) - controlStr += "0"; - controlStr += valueStr + "#"; - serialPort->write(controlStr.c_str()); - serialPort->waitForBytesWritten(); - } -}; -class lightSourceManager : public QThread -{ -public: - lightSourceManager() - { - - - } - void run() - { - init(); - } - void init() - { - insertLightSource("COM9", 19200, "SA0000#SB0000#SC0000#SD0000#"); - } - std::unordered_maplightSources; - void insertLightSource(std::string comName ,int baudRate,std::string initStr) - { - lightSource* newLigthSource = new lightSource(comName, baudRate, initStr); - lightSources.insert(std::make_pair(comName, newLigthSource)); - } - lightSource* getLightSourcePtr(std::string comName) - { - auto ptr = lightSources.find(comName); - if (ptr != lightSources.end()) - return ptr->second; - return nullptr; - } -}; -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/simpleTools/sharedMem.h b/src/launcher/GUI/simpleTools/sharedMem.h deleted file mode 100644 index e0ecb3e..0000000 --- a/src/launcher/GUI/simpleTools/sharedMem.h +++ /dev/null @@ -1,84 +0,0 @@ - -#include -#include -#define memSize 512 -bool writeSharedMem(std::string memName,std::string text) -{ - char* memNameChar = (char*)(memName.c_str()); - HANDLE hMapFile = OpenFileMapping( - FILE_MAP_ALL_ACCESS, // 读/写访问 - FALSE, // 句柄不继承 - memNameChar // 共享内存对象的名称 - ); - - if (hMapFile == NULL) - { - hMapFile = CreateFileMapping( - INVALID_HANDLE_VALUE, // 使用分页文件 - NULL, // 默认安全性 - PAGE_READWRITE, // 读/写访问 - 0, // 最大对象大小(高位32位) - memSize, // 最大对象大小(低位32位) - memNameChar // 共享内存对象的名称 - ); - } - if (hMapFile == NULL) - return false; - - char* pBuf = (char*)MapViewOfFile( - hMapFile, // 共享内存对象的句柄 - FILE_MAP_ALL_ACCESS, // 读/写权限 - 0, - 0, - memSize - ); - if (pBuf == NULL) { - std::cerr << "Could not map view of file (" << GetLastError() << ")." << std::endl; - CloseHandle(hMapFile); - return false; - } - strcpy(pBuf, text.c_str()); - UnmapViewOfFile(pBuf); - //CloseHandle(hMapFile); -} -std::string readSharedMem(std::string memName) -{ - char* memNameChar = (char*)(memName.c_str()); - HANDLE hMapFile = OpenFileMapping( - FILE_MAP_ALL_ACCESS, // 读/写访问 - FALSE, // 句柄不继承 - memNameChar // 共享内存对象的名称 - ); - if (hMapFile == NULL) - { - std::cerr << "Could not open file mapping object (" << GetLastError() << ")." << std::endl; - return "notFound"; - } - char* pBuf = (char*)MapViewOfFile( - hMapFile, // 共享内存对象的句柄 - FILE_MAP_ALL_ACCESS, // 读/写权限 - 0, - 0, - memSize - ); - std::string reuslt = pBuf; - UnmapViewOfFile(pBuf); - //CloseHandle(hMapFile); - return reuslt; -} -bool releaseSharedMem(std::string memName) -{ - char* memNameChar = (char*)(memName.c_str()); - HANDLE hMapFile = OpenFileMapping( - FILE_MAP_ALL_ACCESS, // 读/写访问 - FALSE, // 句柄不继承 - memNameChar // 共享内存对象的名称 - ); - if (hMapFile == NULL) - { - return false; - } - CloseHandle(hMapFile); - return true; -} -#pragma once diff --git a/src/launcher/GUI/simpleTools/simpleSiemensTcp.hpp b/src/launcher/GUI/simpleTools/simpleSiemensTcp.hpp deleted file mode 100644 index dc1587c..0000000 --- a/src/launcher/GUI/simpleTools/simpleSiemensTcp.hpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include - -class simpleSiemensTcp : public QTcpSocket -{ - Q_OBJECT - -public: - simpleSiemensTcp(QObject* parent = nullptr) : QTcpSocket(parent) { - connect(this, &QTcpSocket::connected, this, &simpleSiemensTcp::onConnected); - connect(this, &QTcpSocket::disconnected, this, &simpleSiemensTcp::onDisconnected); - connect(this, &QTcpSocket::readyRead, this, &simpleSiemensTcp::onReadyRead); - //connect(this, QOverload::of(&QTcpSocket::errorOccurred), - // this, &simpleSiemensTcp::onErrorOccurred); - connectToServer("192.168.10.1", 102); - waitForConnected(); - //"03 00 00 16 11 E0 00 00 00 01 00 C0 01 0A C1 02 01 02 C2 02 01 00 "TC - //"03 00 00 19 02 F0 80 32 01 00 00 04 00 00 08 00 00 F0 00 00 01 00 01 01 E0" catch - write(QByteArray::fromHex("03 00 00 16 11 E0 00 00 00 01 00 C0 01 0A C1 02 01 02 C2 02 01 00")); - waitForBytesWritten(); - write(QByteArray::fromHex("03 00 00 1B 02 F0 80 32 03 00 00 04 00 00 08 00 00 00 00 F0 00 00 01 00 01 00 F0")); - waitForBytesWritten(); - writeDM100FALSE(); - } -public slots: - void writeDM100TRUE() - { - //"03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0E 00 05 05 01 12 0A 10 01 00 01 00 00 83 00 03 20 00 03 00 01 01 "TC - //"03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 01" catch - //"03 00 00 24 02 F0 80 32 01 00 00 00 05 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 01" - write(QByteArray::fromHex("03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 01")); - waitForBytesWritten(); - //write(QByteArray::fromHex("03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 01")); - //waitForBytesWritten(); - //write(QByteArray::fromHex("03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 01")); - //waitForBytesWritten(); - } - void writeDM100FALSE() - { - //"03 00 00 24 02 F0 80 32 01 00 00 00 03 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 00" - write(QByteArray::fromHex("03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 00")); - waitForBytesWritten(); - //write(QByteArray::fromHex("03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 00")); - //waitForBytesWritten(); - //write(QByteArray::fromHex("03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0e 00 05 05 01 12 0a 10 01 00 01 00 00 83 00 03 20 00 03 00 01 00")); - //waitForBytesWritten(); - } - void connectToServer(const QString& host, quint16 port) { - connectToHost(host, port); - } - - void sendMessage(const QString& message) { - if (state() == QAbstractSocket::ConnectedState) { - write(message.toUtf8()); - } - } - -signals: - void messageReceived(const QString& message); - -private slots: - void onConnected() { - qDebug() << "Connected to server"; - } - - void onDisconnected() { - qDebug() << "Disconnected from server"; - } - - void onReadyRead() { - QByteArray data = readAll(); - emit messageReceived(QString::fromUtf8(data)); - } - - void onErrorOccurred(QAbstractSocket::SocketError socketError) { - qDebug() << "Error occurred:" << socketError << errorString(); - } -}; -//class simpleSiemensTcp :public QThread -//{ -// Q_OBJECT -// public: -// QTcpSocket* socket; -// simpleSiemensTcp() -// { -// socket = new QTcpSocket(); -// QObject::connect(socket, &QTcpSocket::connected, [&]() { -// //std::cout << "Connected to server." << std::endl; -// //socket->write("hello"); // 发送 "hello" -// //socket->flush(); // 确保数据被发送 -// //socket->disconnectFromHost(); // 断开连接 -// }); -// -// QObject::connect(socket, &QTcpSocket::disconnected, [&]() { -// std::cout << "Disconnected from server." << std::endl; -// }); -// -// -// socket->connectToHost(QHostAddress("192.168.50.214"), 102); -// socket->waitForConnected(); -// socket->write("hello"); // 发送 "hello" -// socket->flush(); // 确保数据被发送 -// socket->waitForBytesWritten(); -// } -// void run() -// { -// //while(1) -// -// } -//}; \ No newline at end of file diff --git a/src/launcher/GUI/simpleTools/stringAlgo.h b/src/launcher/GUI/simpleTools/stringAlgo.h deleted file mode 100644 index 3e43e40..0000000 --- a/src/launcher/GUI/simpleTools/stringAlgo.h +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -static std::vector split(const std::string& s, char delimiter) { - std::vector tokens; - std::string token; - std::stringstream ss(s); // 创建字符串流 - - // 使用 std::getline 从字符串流中读取以分隔符分隔的子字符串 - while (std::getline(ss, token, delimiter)) { - tokens.push_back(token); - } - - return tokens; -} -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/simpleTools/windowsHardwareCtrl.hpp b/src/launcher/GUI/simpleTools/windowsHardwareCtrl.hpp deleted file mode 100644 index 9022b5c..0000000 --- a/src/launcher/GUI/simpleTools/windowsHardwareCtrl.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include -#include -#include // for strstr -#include - -#pragma comment(lib, "setupapi.lib") - -static void DisableComPort(const char* portName) { - HDEVINFO hDevInfo; - SP_DEVINFO_DATA DeviceInfoData; - DWORD i; - - // Get the device information set for all present devices. - hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT); - if (hDevInfo == INVALID_HANDLE_VALUE) { - printf("SetupDiGetClassDevs 失败: %ld\n", GetLastError()); - return; - } - - - // Enumerate through all devices in the set. - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { - DWORD DataT; - char buffer[4096]; - DWORD buffersize = sizeof(buffer); - - // Get the friendly name of the device. - if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { - if (strstr(buffer, portName) != NULL) { - printf("Found COM port: %s\n", buffer); - - // Disable the device. - DEVINST devInst = DeviceInfoData.DevInst; - CONFIGRET status = CM_Disable_DevNode(devInst, 0); - if (status != CR_SUCCESS) { - printf("CM_Disable_DevNode failed: %d\n", status); - } - else { - printf("Device disabled successfully.\n"); - } - break; - } - } - } if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) { - printf("SetupDiEnumDeviceInfo failed: %ld\n", GetLastError()); - } - - // Cleanup - SetupDiDestroyDeviceInfoList(hDevInfo); -} -static void EnableComPort(const char* portName) { - HDEVINFO hDevInfo; - SP_DEVINFO_DATA DeviceInfoData; - DWORD i; - - // Get the device information set for all present devices. - hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT); - if (hDevInfo == INVALID_HANDLE_VALUE) { - printf("SetupDiGetClassDevs 失败: %ld\n", GetLastError()); - return; - } - - - // Enumerate through all devices in the set. - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { - DWORD DataT; - char buffer[4096]; - DWORD buffersize = sizeof(buffer); - - // Get the friendly name of the device. - if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { - if (strstr(buffer, portName) != NULL) { - printf("Found COM port: %s\n", buffer); - - // Disable the device. - DEVINST devInst = DeviceInfoData.DevInst; - CONFIGRET status = CM_Enable_DevNode(devInst, 0); - if (status != CR_SUCCESS) { - printf("CM_Enable_DevNode failed: %d\n", status); - } - else { - printf("Device Enable successfully.\n"); - } - break; - } - } - } - if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) { - printf("SetupDiEnumDeviceInfo failed: %ld\n", GetLastError()); - } - - // Cleanup - SetupDiDestroyDeviceInfoList(hDevInfo); -} -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/simpleTools/writeCsv.hpp b/src/launcher/GUI/simpleTools/writeCsv.hpp deleted file mode 100644 index d74cfba..0000000 --- a/src/launcher/GUI/simpleTools/writeCsv.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -void writeCSV(const std::string& filename, const std::vector>& data) { - std::ofstream file(filename); - - if (!file.is_open()) { - std::cerr << "无法打开文件:" << filename << std::endl; - return; - } - - for (const auto& row : data) { - for (size_t i = 0; i < row.size(); ++i) { - file << row[i]; - if (i < row.size() - 1) { - file << ","; - } - } - file << "\n"; - } - - file.close(); -} - -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/jsonExamlpe.json b/src/launcher/GUI/uiModule/jsonExamlpe.json new file mode 100644 index 0000000..c372f7d --- /dev/null +++ b/src/launcher/GUI/uiModule/jsonExamlpe.json @@ -0,0 +1,13 @@ +{ +"waveForm":{ + "height": 0, + "key": "包膜前外观检测大面相机1(上大面)合格率", + "limitHigh": 100.0, + "limitLow": 0.0, + "maxPoints": 100, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 0, + "y": 0 + } +} \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/uiChart_WaveForm.h b/src/launcher/GUI/uiModule/uiChart_WaveForm.h new file mode 100644 index 0000000..b515dab --- /dev/null +++ b/src/launcher/GUI/uiModule/uiChart_WaveForm.h @@ -0,0 +1,309 @@ +#include +#include + +static nlohmann::ordered_json genWaveFormWidgetJson + (std::string title,int limitHigh,int limitLow,int maxPoints) { + nlohmann::ordered_json result; + result["key"] = title; + result["limitHigh"] = limitHigh; + result["limitLow"] = limitLow; + result["maxPoints"] = maxPoints; + return result; +} +class WaveFormWidget : public QWidget { + Q_OBJECT +public: + WaveFormWidget(nlohmann::ordered_json& json, QWidget* parent = nullptr) + : QWidget(parent), m_json(json), + m_mainLayout(new QVBoxLayout(this)), + m_title(new QLabel(this)), + m_plot(new QCustomPlot(this)) + { + QString title = QString::fromStdString(json.value("key", "默认标题")); + m_limitHigh = json.value("limitHigh", 100.0); + m_limitLow = json.value("limitLow", 0.0); + m_maxPoints = json.value("maxPoints", 50); + + QFont font("微软雅黑", 24, QFont::Bold); + QPalette palette; + palette.setColor(QPalette::WindowText, Qt::white); + + setObjectName("WaveFormWidget"); + setStyleSheet("QWidget#WaveFormWidget {background-color: rgb(100,100,255);}"); + m_title->setText(title); + m_title->setFixedHeight(60); + m_title->setAlignment(Qt::AlignHCenter); + m_title->setPalette(palette); + m_title->setFont(font); + + m_mainLayout->addWidget(m_title); + m_mainLayout->addWidget(m_plot); + + m_plot->setBackground(Qt::transparent); + + // 主蓝色曲线 + m_plot->addGraph(); + m_plot->graph(0)->setPen(QPen(QColor(0, 191, 255), 3)); + m_plot->graph(0)->setScatterStyle(QCPScatterStyle::ssNone); + + // 新增红色点图层 + m_plot->addGraph(); + m_plot->graph(1)->setLineStyle(QCPGraph::lsNone); + m_plot->graph(1)->setScatterStyle( + QCPScatterStyle(QCPScatterStyle::ssDisc, QPen(Qt::red), QBrush(Qt::red), 5) + ); + m_plot->xAxis->setBasePen(QPen(Qt::white, 2)); // 坐标轴线 + m_plot->yAxis->setBasePen(QPen(Qt::white, 2)); + + m_plot->xAxis->setTickPen(QPen(Qt::white)); // 刻度线 + m_plot->yAxis->setTickPen(QPen(Qt::white)); + + m_plot->xAxis->setSubTickPen(QPen(Qt::white)); // 次刻度 + m_plot->yAxis->setSubTickPen(QPen(Qt::white)); + + m_plot->xAxis->setTickLabelColor(Qt::white); // 数字标签 + m_plot->yAxis->setTickLabelColor(Qt::white); + + m_plot->xAxis->setLabelColor(Qt::white); // "时间" / "数值" 文字 + m_plot->yAxis->setLabelColor(Qt::white); + + + + // 鼠标追踪 + m_tracer = new QCPItemTracer(m_plot); + m_tracer->setGraph(m_plot->graph(0)); // 追踪蓝色曲线 + m_tracer->setStyle(QCPItemTracer::tsCircle); + m_tracer->setPen(QPen(Qt::yellow)); + m_tracer->setBrush(Qt::yellow); + m_tracer->setSize(7); + m_tracer->setVisible(false); // 默认隐藏 + + // 文本提示 + m_tracerText = new QCPItemText(m_plot); + m_tracerText->setColor(Qt::white); // 文字颜色 + m_tracerText->setFont(QFont("微软雅黑", 10, QFont::Bold)); + m_tracerText->position->setType(QCPItemPosition::ptPlotCoords); + m_tracerText->setBrush(QBrush(QColor(0, 0, 0, 150))); // 半透明背景 + m_tracerText->setPadding(QMargins(5, 2, 5, 2)); // 留点内边距 + m_tracerText->setVisible(false); + + // 绑定鼠标移动事件 + connect(m_plot, &QCustomPlot::mouseMove, this, &WaveFormWidget::onMouseMoveInPlot); + if (title.contains("对齐度")) { + auto fixedTicker = QSharedPointer(new QCPAxisTickerFixed); + fixedTicker->setTickStep(0.1); + fixedTicker->setScaleStrategy(QCPAxisTickerFixed::ssNone); // 不自动放大 + m_plot->yAxis->setTicker(fixedTicker); + m_plot->yAxis->setRange(-0.2, 0.8); + } + else + updateYrange(m_limitLow, m_limitHigh); + + + addLimitLines(m_limitHigh, m_limitLow); + } + void updateYrange(double low, double high) { + if (fixedHigh == -1 || fixedLow == -1) + m_plot->yAxis->setRange(qMax(0.0, m_limitLow - (m_limitHigh - m_limitLow)), m_limitHigh + 2); + else + m_plot->yAxis->setRange(fixedLow, fixedHigh); + } + void appendData(double value) { + QMutexLocker locker(&mutex); + m_xData.append(m_timeCounter); + m_yData.append(value); + + // 超限 + if (value > m_limitHigh || value < m_limitLow) { + m_xOverLimit.append(m_timeCounter); + m_yOverLimit.append(value); + + //auto* textItem = new QCPItemText(m_plot); + //textItem->setPositionAlignment(Qt::AlignLeft | Qt::AlignBottom); + //textItem->position->setType(QCPItemPosition::ptPlotCoords); + //textItem->position->setCoords(m_timeCounter, value); + //textItem->setText(QString::number(value, 'f', 2)); + //textItem->setColor(Qt::yellow); + //textItem->setFont(QFont("微软雅黑", 8,QFont::Bold)); + //m_textItems.append(textItem); + } + + ++m_timeCounter; + + // 保持窗口大小 + if (m_xData.size() > m_maxPoints) { + m_xData.removeFirst(); + m_yData.removeFirst(); + } + if (m_xOverLimit.size() > m_maxPoints) { + m_xOverLimit.removeFirst(); + m_yOverLimit.removeFirst(); + } + + // 清理超出窗口范围的文本 + while (!m_textItems.isEmpty() && m_textItems.first()->position->key() < m_timeCounter - m_maxPoints) { + m_plot->removeItem(m_textItems.first()); + m_textItems.removeFirst(); + } + + m_plot->graph(0)->setData(m_xData, m_yData); + m_plot->graph(1)->setData(m_xOverLimit, m_yOverLimit); + m_plot->xAxis->setRange(qMax(0.0, m_timeCounter - m_maxPoints), m_timeCounter); + m_plot->replot(); + } + void setFixedYrange(double low, double high) { + fixedHigh = high; + fixedLow = low; + updateYrange(0, 100); + } + +protected: + void contextMenuEvent(QContextMenuEvent* event) override { + QMenu menu(this); + menu.addAction("编辑参数", this, &WaveFormWidget::editJsonParameters); + menu.exec(event->globalPos()); + } + + void leaveEvent(QEvent* event) override { + if (m_tracer) m_tracer->setVisible(false); + if (m_tracerText) m_tracerText->setVisible(false); + m_plot->replot(); + QWidget::leaveEvent(event); + } +#if switchToTongYongUi == 1 + void paintEvent(QPaintEvent* event) override { + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + int radius = 10; // 圆角半径 + QRect r = rect(); + + // 填充圆角背景 + painter.setBrush(QColor(50, 55, 60)); + painter.setPen(Qt::NoPen); + painter.drawRoundedRect(r, radius, radius); + } +#endif +private slots: + void editJsonParameters() { + JsonParamTableEditor* dlg = new JsonParamTableEditor(this); + dlg->setJsonObject(m_json); + dlg->setAttribute(Qt::WA_DeleteOnClose); + connect(dlg, &JsonParamTableEditor::jsonAccepted, [this](const nlohmann::json& result) { + m_json = result; + applyJsonParams(); + }); + dlg->show(); + } + void onMouseMoveInPlot(QMouseEvent* event) { + double x = m_plot->xAxis->pixelToCoord(event->pos().x()); + if (!m_xData.isEmpty()) { + double y = findNearestYValue(x); + + m_tracer->setGraphKey(x); + m_tracer->updatePosition(); + m_tracer->setVisible(true); + + m_tracerText->setText(QString("%1\n值:%2") + .arg(static_cast(std::round(x))) + .arg(y, 0, 'f', 2)); + m_tracerText->setVisible(true); + m_tracerText->setTextAlignment(Qt::AlignLeft); + + // 判断左右边显示气泡 + int mouseX = event->pos().x(); + int mouseY = event->pos().y(); + int plotWidth = m_plot->width(); + int plotHeight = m_plot->height(); + + Qt::Alignment hAlign = (mouseX < plotWidth / 2) ? Qt::AlignLeft : Qt::AlignRight; + Qt::Alignment vAlign = (mouseY < plotHeight / 2) ? Qt::AlignTop : Qt::AlignBottom; + + m_tracerText->setPositionAlignment(hAlign | vAlign); + + m_tracerText->position->setCoords(x, y); + m_plot->replot(); + } + } + +private: + void applyJsonParams() { + QMutexLocker locker(&mutex); // 确保线程安全 + m_maxPoints = m_json.value("maxPoints", m_maxPoints); + m_limitHigh = m_json.value("limitHigh", m_limitHigh); + m_limitLow = m_json.value("limitLow", m_limitLow); + + m_title->setText(QString::fromStdString(m_json.value("key", m_title->text().toStdString()))); + m_plot->clearItems(); + addLimitLines(m_limitHigh, m_limitLow); + + // 更新坐标范围 + updateYrange(m_limitLow, m_limitHigh); + + // 清空超限数据 + m_xOverLimit.clear(); + m_yOverLimit.clear(); + + m_plot->replot(); + } + + // 简单线性插值(或者最近点) + double interpolateYValue(double x) { + for (int i = 1; i < m_xData.size(); ++i) { + if (m_xData[i] >= x) { + double x0 = m_xData[i - 1], y0 = m_yData[i - 1]; + double x1 = m_xData[i], y1 = m_yData[i]; + if (x1 == x0) return y0; + return y0 + (y1 - y0) * (x - x0) / (x1 - x0); + } + } + return m_yData.last(); // 超出范围 + } + double findNearestYValue(double x) { + if (m_xData.isEmpty()) + return 0; + + int nearestIndex = 0; + double minDist = std::abs(m_xData[0] - x); + + for (int i = 1; i < m_xData.size(); ++i) { + double dist = std::abs(m_xData[i] - x); + if (dist < minDist) { + minDist = dist; + nearestIndex = i; + } + } + + return m_yData[nearestIndex]; + } + + void addLimitLines(double high, double low) { + auto* line1 = new QCPItemStraightLine(m_plot); + line1->setPen(QPen(Qt::green, 1, Qt::SolidLine)); + line1->point1->setCoords(0, high); + line1->point2->setCoords(1, high); + + auto* line2 = new QCPItemStraightLine(m_plot); + line2->setPen(QPen(Qt::green, 1, Qt::SolidLine)); + line2->point1->setCoords(0, low); + line2->point2->setCoords(1, low); + } + + nlohmann::ordered_json& m_json; + QVBoxLayout* m_mainLayout; + QLabel* m_title; + QCustomPlot* m_plot; + QList m_textItems; + QVector m_xData, m_yData; + QVector m_xOverLimit, m_yOverLimit; // 新增用于红色点 + int m_maxPoints = 50; + double m_timeCounter = 0; + double m_limitHigh = -1, m_limitLow = 2; + double fixedHigh = -1, fixedLow = -1; + QCPItemTracer* m_tracer = nullptr; + QCPItemText* m_tracerText = nullptr; +private: + QMutex mutex; +}; + +#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h b/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h index 376723f..3e9a66c 100644 --- a/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h +++ b/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #define cacheSqlFileName "sqlite-database-copy.db" diff --git a/src/launcher/GUI/uiModule/uiModule_imageView.h b/src/launcher/GUI/uiModule/uiModule_imageView.h index 980995d..855bfd2 100644 --- a/src/launcher/GUI/uiModule/uiModule_imageView.h +++ b/src/launcher/GUI/uiModule/uiModule_imageView.h @@ -269,8 +269,8 @@ public: QHBoxLayout* hLayout = new QHBoxLayout(hWidget); hWidget->setFixedHeight(16); - auto spaceItem = new QSpacerItem(100, 1); - hLayout->addSpacerItem(spaceItem); + /* auto spaceItem = new QSpacerItem(100, 1); + hLayout->addSpacerItem(spaceItem);*/ label = new QLabel(u8"相机标签"); label->setAlignment(Qt::AlignLeft); @@ -287,7 +287,7 @@ public: { switchViewType(type); }); - + switchBox.hide(); label->setAlignment(Qt::AlignCenter); hLayout->addWidget(label); hLayout->addWidget(&switchBox); @@ -295,7 +295,7 @@ public: //hLayout->addWidget(switchBtn); - layout->addWidget(hWidget); + layout->addWidget(hWidget); layout->addWidget(viewer); viewer->setDragMode(QGraphicsView::ScrollHandDrag); diff --git a/src/launcher/appConfig/appConfig.h b/src/launcher/appConfig/appConfig.h index 9b9bf93..df74267 100644 --- a/src/launcher/appConfig/appConfig.h +++ b/src/launcher/appConfig/appConfig.h @@ -21,6 +21,7 @@ public: std::string softwareTile;//软件标题 std::string imgSavePath;//原图存储路径 SQLiteDB* g_db = nullptr; + HWND consoleHandle; //triggerStruct _triggerStruct; //std::vector< cameraStruct> _cameraStructs; //sqlConfigStruct _sqlConfigStruct; diff --git a/src/launcher/appCore.hpp b/src/launcher/appCore.hpp index 72a35b9..441f2a3 100644 --- a/src/launcher/appCore.hpp +++ b/src/launcher/appCore.hpp @@ -57,10 +57,6 @@ public: appConfig _appConfig; backEnd backend; - appCore(){ - - }; - public slots: void switchProductSignal(){ diff --git a/src/launcher/hardwareInfo/fetchHardwareMonitor.h b/src/launcher/hardwareInfo/fetchHardwareMonitor.h new file mode 100644 index 0000000..90ddc83 --- /dev/null +++ b/src/launcher/hardwareInfo/fetchHardwareMonitor.h @@ -0,0 +1,181 @@ +#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/hardwareInfo/hardwareInfo.h b/src/launcher/hardwareInfo/hardwareInfo.h new file mode 100644 index 0000000..55e5308 --- /dev/null +++ b/src/launcher/hardwareInfo/hardwareInfo.h @@ -0,0 +1,365 @@ +#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(); + } + } + double getAvgMemUseage() { + hwinfo::Memory memory; + return 1.0 - memory.free_Bytes() / memory.total_Bytes(); + } +#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; +}; +class hardwareInfoThread : public QThread { + Q_OBJECT +public: + int retryCnt = 0, retryMax = 10; + hardwareInfoThread() { + startProcess("./LibreHardwareMonitor/LibreHardwareMonitor.exe"); + } + ~hardwareInfoThread() { + quit(); + wait(); + } + void startProcess(const QString& exePath) { + if (process) return; // 避免重复启动 + + process = new QProcess(); + process->setProgram(exePath); + process->start(); + + if (!process->waitForStarted(1000)) { + qDebug() << "Process failed to start."; + delete process; + process = nullptr; + return; + } + + DWORD pid = process->processId(); + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + + jobHandle = CreateJobObject(nullptr, nullptr); + if (jobHandle == nullptr) { + qDebug() << "Failed to create job object"; + return; + } + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {}; + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + SetInformationJobObject(jobHandle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)); + + if (!AssignProcessToJobObject(jobHandle, hProcess)) { + qDebug() << "Failed to assign process to job object"; + } + + CloseHandle(hProcess); + } +protected: + void run() override { + JsonFetcher* fetcher = new JsonFetcher; + fetcher->moveToThread(this); + + connect(fetcher, &JsonFetcher::jsonReady, this, [this](const QJsonObject& obj) { + //qDebug() << calculateOverallCpuLoad(obj); + //qDebug() << calculateOverallCpuTemperature(obj); + //qDebug() << parseMemoryUsage(obj); + emit addCpuUsageData(calculateOverallCpuLoad(obj)); + emit addCpuTempData(calculateMaxCpuTemperature(obj)); + emit addMemUsageData(parseMemoryUsage(obj)); + }); + connect(fetcher, &JsonFetcher::error, this, [](const QString& err) { + //qWarning() << "Error:" << err; + }); + + // 定时器驱动 fetch + QTimer timer; + connect(&timer, &QTimer::timeout, fetcher, [fetcher]() { + fetcher->fetch(QUrl("http://127.0.0.1:8085/data.json")); + }); + timer.start(2000); + + exec(); // 启动事件循环 + } +signals: + void addCpuUsageData(double input); + void addCpuTempData(double input); + void addMemUsageData(double input); +}; + +class hardwareInfoWidget : public QWidget { + Q_OBJECT +public: + hardwareInfoThread _hardwareInfoThread; + hardwareInfoWidget() { + connect(&_hardwareInfoThread, &hardwareInfoThread::addCpuUsageData, this, &hardwareInfoWidget::addCpuUsageData); + connect(&_hardwareInfoThread, &hardwareInfoThread::addCpuTempData, this, &hardwareInfoWidget::addCpuTempData); + connect(&_hardwareInfoThread, &hardwareInfoThread::addMemUsageData, this, &hardwareInfoWidget::addMemUsageData); + jsonMap["CPUUSAGE"] = genWaveFormWidgetJson("cpu_usage", 80, 0, 240); + waveForms["CPUUSAGE"] = new WaveFormWidget(jsonMap["CPUUSAGE"]); + layout->addWidget(waveForms["CPUUSAGE"]); + + jsonMap["CPUTEMP"] = genWaveFormWidgetJson("cpu_temp", 80, 0, 240); + waveForms["CPUTEMP"] = new WaveFormWidget(jsonMap["CPUTEMP"]); + layout->addWidget(waveForms["CPUTEMP"]); + + jsonMap["MEMUSAGE"] = genWaveFormWidgetJson("mem_useage", 80, 0, 240); + waveForms["MEMUSAGE"] = new WaveFormWidget(jsonMap["MEMUSAGE"]); + layout->addWidget(waveForms["MEMUSAGE"]); + + for (auto& widget : waveForms) { + widget->setMinimumWidth(720); + widget->setMinimumHeight(200); + widget->setFixedYrange(0, 100); + } + _hardwareInfoThread.start(); + } +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); +}; + +#pragma once \ No newline at end of file diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 36225f1..8e1d8b5 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -1,5 +1,5 @@ #include -//#include "client/windows/handler/exception_handler.h" +#include "client/windows/handler/exception_handler.h" #include #include #include @@ -85,25 +85,25 @@ void restartAsAdmin() } } #pragma endregion -//static bool dumpCallback(const wchar_t* dump_path, -// const wchar_t* minidump_id, -// void* context, -// EXCEPTION_POINTERS* exinfo, -// MDRawAssertionInfo* assertion, -// bool succeeded) { -// wprintf(L"Dump created at %s\\%s.dmp\n", dump_path, minidump_id); -// return succeeded; -//} -//bool checkResourceExists(const QString& resourcePath) { -// if (QFile::exists(resourcePath)) { -// qDebug() << "文件存在:" << resourcePath; -// return true; -// } -// else { -// qDebug() << "文件不存在:" << resourcePath; -// return false; -// } -//} +static bool dumpCallback(const wchar_t* dump_path, + const wchar_t* minidump_id, + void* context, + EXCEPTION_POINTERS* exinfo, + MDRawAssertionInfo* assertion, + bool succeeded) { + wprintf(L"Dump created at %s\\%s.dmp\n", dump_path, minidump_id); + return succeeded; +} +bool checkResourceExists(const QString& resourcePath) { + if (QFile::exists(resourcePath)) { + qDebug() << "文件存在:" << resourcePath; + return true; + } + else { + qDebug() << "文件不存在:" << resourcePath; + return false; + } +} void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* bridge) { QObject::connect(_core->_logService._logToQtWidget, &logToQtWidget::stdLogSignal, @@ -164,6 +164,7 @@ int main(int argc, char* argv[]) // restartAsAdmin(); // exit(0); //} + #pragma region 设置显示控制栏 HWND hWnd = GetConsoleWindow(); ShowWindow(hWnd, SW_SHOW); @@ -173,16 +174,17 @@ int main(int argc, char* argv[]) CreateDirectoryW(dumpPath.c_str(), nullptr); // 初始化 breakpad - //google_breakpad::ExceptionHandler eh( - // dumpPath, - // /*FilterCallback*/ nullptr, - // dumpCallback, - // /*context*/ nullptr, - // /*install_handler*/ true - //); + google_breakpad::ExceptionHandler eh( + dumpPath, + /*FilterCallback*/ nullptr, + dumpCallback, + /*context*/ nullptr, + /*install_handler*/ true + ); #pragma endregion appCore _core; + _core._appConfig.consoleHandle = hWnd; qtFuncBridge bridge; // 创建 C++ 对象 //检测是否已运行 if (appIsRuning() == false) @@ -200,6 +202,8 @@ int main(int argc, char* argv[]) qRegisterMetaType>("vectorstring"); #pragma endregion QApplication a(argc, argv); + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/sqldrivers"); + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); MainWindow w(&_core._appConfig,&bridge, _core._appConfig.settingJson); connectSignalAndSlot(&_core, &w, &bridge); // 连接信号和槽 w.show(); @@ -207,8 +211,8 @@ int main(int argc, char* argv[]) // 创建后端对象 _core.backend.loadCore(&bridge, _core._appConfig.settingJson["backend"]); // 加载核心功能 #if HIDE_CONSOLE - if (hWnd) { - ShowWindow(hWnd, SW_HIDE); + if (_core._appConfig.consoleHandle) { + ShowWindow(_core._appConfig.consoleHandle, SW_HIDE); _core._logService.disableConsole(); }// 隐藏控制台窗口 #endif diff --git a/src/mission/581-Mfd_djy_sd/581-Mfd.h b/src/mission/581-Mfd_djy_sd/581-Mfd.h index ab75ee2..888850e 100644 --- a/src/mission/581-Mfd_djy_sd/581-Mfd.h +++ b/src/mission/581-Mfd_djy_sd/581-Mfd.h @@ -232,7 +232,7 @@ public: mapData["偏移X"] = resultData.x; mapData["偏移Y"] = resultData.y; mapData["结果"] = resultData.result; - _serviceManager->_csvWriter->addtData(QString::fromStdString(data->SNcode), mapData); + _serviceManager->_csvWriter->addData(QString::fromStdString(data->SNcode), mapData); } private: qtFuncBridge* bridge; 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 2bab84b..20f93ac 100644 --- a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h +++ b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h @@ -534,7 +534,7 @@ public: mapData["偏移X"] = resultData.x; mapData["偏移Y"] = resultData.y; mapData["结果"] = resultData.result; - _serviceManager->_csvWriter->addtData(QString::fromStdString(data->SNcode), mapData); + _serviceManager->_csvWriter->addData(QString::fromStdString(data->SNcode), mapData); } private: qtFuncBridge* bridge; @@ -590,7 +590,7 @@ public: mapData["偏移X"] = resultData.x; mapData["偏移Y"] = resultData.y; mapData["结果"] = resultData.result; - _serviceManager->_csvWriter->addtData(QString::fromStdString(data->SNcode), mapData); + _serviceManager->_csvWriter->addData(QString::fromStdString(data->SNcode), mapData); } private: qtFuncBridge* bridge; diff --git a/src/mission/581-Ruke/581-Ruke.h b/src/mission/581-Ruke/581-Ruke.h index 3d715f4..187dce6 100644 --- a/src/mission/581-Ruke/581-Ruke.h +++ b/src/mission/581-Ruke/581-Ruke.h @@ -109,6 +109,7 @@ public: } //9200 1 void evaluate(int triggerPos, int triggerValue, int snPos, int finishSignalPos, QByteArray& byteArray) { + _serviceManager->_csvWriter->addData("ww", { {"hh","zz"} }); _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(finishSignalPos) + "_1");//完成信号 std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); auto camera = _serviceManager->_cameraManager->getCamera(cameraName);