阶段备份,SQL逻辑修改,去除配置文件。rpc读取逻辑更改。
This commit is contained in:
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
+2
-1
@@ -9,7 +9,8 @@
|
||||
#include <functional>
|
||||
#pragma execution_character_set("utf-8")
|
||||
const std::string softwareVersion = "2.0.2";
|
||||
const std::string euiJsonVersion = "1.0.5";
|
||||
const std::string euiJsonVersion = "1.0.6";
|
||||
#define saveImgEnable 1
|
||||
#define switchToTongYongUi 1 //是否切换到通用UI界面
|
||||
#define skipLogin 1 //是否跳过登录界面
|
||||
#define sColor_Blue "51, 56, 69"
|
||||
|
||||
@@ -8,6 +8,7 @@ public:
|
||||
virtual void init(qtFuncBridge*,nlohmann::ordered_json& json) = 0;
|
||||
virtual void cleanup() = 0;
|
||||
virtual SQLiteDB* getDatabase() = 0;
|
||||
virtual bool excuteCliCommandPreset(const QString& uuid) = 0;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
+8
-1
@@ -44,7 +44,10 @@ signals:
|
||||
void pieWidgetAddNG();
|
||||
void pieWidgetAddOK();
|
||||
void histogramWidgetAddData(std::vector<std::string>);
|
||||
|
||||
void setPlcConnectionError();
|
||||
void setPlcConnectionOk();
|
||||
void setCamConnectionError();
|
||||
void setCamConnectionOk();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// 切换界面
|
||||
@@ -68,5 +71,9 @@ signals:
|
||||
void loadingWindow_clearWarningLog();
|
||||
//////////////////////////////////////////////////////////////
|
||||
void reInitConfig();
|
||||
|
||||
//排障
|
||||
void runCommand_addBtn(const QString& btnName, const QString& tip, const QString& uuid);
|
||||
|
||||
};
|
||||
#pragma once
|
||||
+106
-50
@@ -97,7 +97,20 @@ public:
|
||||
bool res = query.exec(sql);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<QString> getTables() {
|
||||
std::vector<QString> tables;
|
||||
// 查询所有表名,排除sqlite系统表
|
||||
QString sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';";
|
||||
QSqlQuery query(m_db);
|
||||
if (!query.exec(sql)) {
|
||||
qDebug() << "getTables failed:" << query.lastError().text();
|
||||
return tables;
|
||||
}
|
||||
while (query.next()) {
|
||||
tables.push_back(query.value(0).toString());
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
bool dropTable(const QString& tableName) {
|
||||
QString sql = QString("DROP TABLE IF EXISTS %1").arg(tableName);
|
||||
return execute(sql);
|
||||
@@ -317,7 +330,7 @@ public:
|
||||
// 记录开始时间
|
||||
auto start = high_resolution_clock::now();
|
||||
// 查询表中的所有数据
|
||||
QString csvFileName = filePath + "/" + tableName + ".csv";
|
||||
QString csvFileName = filePath;
|
||||
QString sql = QString("SELECT * FROM \"%1\"").arg(tableName);
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
@@ -444,42 +457,94 @@ public:
|
||||
//stopAutoExport();
|
||||
}
|
||||
std::map<QString, QString>csvAndChartLink;
|
||||
void addtData(const QString& snCode, const std::map<QString, QVariant>& data) {
|
||||
std::lock_guard<std::mutex> locker(_mutex);
|
||||
QString currentProcessCsvName = getCurrentProcessCsvName();
|
||||
if (currentProcessCsvName != currentProcessCsvNameCache)
|
||||
if (_db->createTable(currentProcessCsvName, db_InitColumns))
|
||||
currentProcessCsvNameCache = currentProcessCsvName;
|
||||
auto res = _db->_search(currentProcessCsvName, {}, { {"条码",snCode} });
|
||||
if (res.empty() == true)//当前数据为空时查询过去的数据是否为空
|
||||
{
|
||||
auto lastRes = _db->_search(getLastProcessCsvName(), {}, { {"条码",snCode} });
|
||||
if (lastRes.empty() == true)//过去的数据也为空 则视作现在要插入的数据为全新的数据
|
||||
{
|
||||
std::map<QString, QVariant> insertData = data;
|
||||
insertData["条码"] = snCode;
|
||||
insertData["创建时间"] = QDateTime::currentDateTime().toString("hh:mm:ss");
|
||||
insertData["修改时间"] = QDateTime::currentDateTime().toString("hh:mm:ss");
|
||||
_db->_insert(currentProcessCsvName, insertData);
|
||||
bool addtData(const QString& snCode, const std::map<QString, QVariant>& data) {
|
||||
try {
|
||||
if (snCode.isEmpty()) {
|
||||
qWarning() << "addtData: snCode is empty.";
|
||||
return false;
|
||||
}
|
||||
else//过去的数据不为空 更新到过去的数据上
|
||||
{
|
||||
std::map<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = QDateTime::currentDateTime().toString("hh:mm:ss");
|
||||
_db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
if (data.empty()) {
|
||||
qWarning() << "addtData: data is empty.";
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> 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;
|
||||
}
|
||||
|
||||
}
|
||||
else//当前数据不为空 更新到当前数据上
|
||||
{
|
||||
std::map<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = QDateTime::currentDateTime().toString("hh:mm:ss");
|
||||
_db->_update(getCurrentProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
}
|
||||
if (timer.elapsed() > m_intervalMs)
|
||||
{
|
||||
exportCsv();
|
||||
timer.start();
|
||||
// 获取当前表的所有列名
|
||||
QSqlQuery colQuery;
|
||||
QString colSql = QString("PRAGMA table_info(\"%1\")").arg(currentProcessCsvName);
|
||||
QList<QString> 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<QString, QVariant> 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<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = nowTime;
|
||||
opResult = _db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 更新当前数据
|
||||
std::map<QString, QVariant> 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;
|
||||
}
|
||||
}
|
||||
bool isNewData(const QString& snCode) {
|
||||
@@ -528,8 +593,7 @@ private:
|
||||
// }
|
||||
// delete _db;
|
||||
//}
|
||||
void init(SQLiteDB* database_ptr = nullptr)
|
||||
{
|
||||
void init(SQLiteDB* database_ptr = nullptr){
|
||||
std::lock_guard<std::mutex> locker(_mutex);
|
||||
if (database_ptr == nullptr)
|
||||
_db = new SQLiteDB("./sqlDatabse/", "database");
|
||||
@@ -609,20 +673,12 @@ private:
|
||||
return (dateStr + "白班"); // 上一班是白班
|
||||
}
|
||||
}
|
||||
//void startAutoExport(int intervalMs = 10000) {
|
||||
// m_intervalMs = intervalMs;
|
||||
// m_running = true;
|
||||
// this->start();
|
||||
//}
|
||||
//void stopAutoExport() {
|
||||
// m_running = false;
|
||||
// this->wait();
|
||||
//}
|
||||
void exportCsv()
|
||||
{
|
||||
void exportCsv(){
|
||||
//std::lock_guard<std::mutex> locker(_mutex);
|
||||
_db->exportTableToCSV(getLastProcessCsvName(), "./csv/", _mutex);
|
||||
_db->exportTableToCSV(getCurrentProcessCsvName(), "./csv/", _mutex);
|
||||
QString name = getLastProcessCsvName();
|
||||
_db->exportTableToCSV(name, "./csv/"+ name +".csv", _mutex);
|
||||
name = getCurrentProcessCsvName();
|
||||
_db->exportTableToCSV(name, "./csv/" + name + ".csv", _mutex);
|
||||
QString currentProcessCsvName = getCurrentProcessCsvName();
|
||||
if (currentProcessCsvName != currentProcessCsvNameCache)
|
||||
if (!_db->createTable(currentProcessCsvName, db_InitColumns)) {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
@@ -37,6 +37,10 @@
|
||||
<file>icon/rollback.png</file>
|
||||
<file>icon/plugin.png</file>
|
||||
<file>icon/summary_data.png</file>
|
||||
<file>icon/lan_connection_error.png</file>
|
||||
<file>icon/lan_connection_ok.png</file>
|
||||
<file>icon/cam_connection_error.png</file>
|
||||
<file>icon/cam_connection_ok.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/TongYongUiIcon">
|
||||
<file>TongYongUiIcon/0.cameraModule.png</file>
|
||||
|
||||
@@ -61,8 +61,8 @@ bool rpc_finsTcp::readData(std::vector<cv::Mat>& 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 = variantListToByteArray(result);
|
||||
// auto result = read_JsonRpcClient[data]->call("excuteCli", QJsonArray{QString(data)}, "finstcp");
|
||||
data = ptr->finsReadCall("excuteCli", QString(data), "finstcp");
|
||||
return true;
|
||||
}
|
||||
bool ifRetryCMD = false;
|
||||
@@ -219,52 +219,122 @@ bool JsonRpcClient::reconnect() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
QVariant jsonToVariant(const nlohmann::json& j)
|
||||
{
|
||||
if (j.is_null()) return QVariant();
|
||||
if (j.is_boolean()) return j.get<bool>();
|
||||
if (j.is_number_integer()) return j.get<qint64>();
|
||||
if (j.is_number_unsigned()) return static_cast<quint64>(j.get<std::uint64_t>());
|
||||
if (j.is_number_float()) return j.get<double>();
|
||||
if (j.is_string()) return QString::fromStdString(j.get<std::string>());
|
||||
|
||||
QVariant JsonRpcClient::call(const QString& method, const QJsonArray& params, const QString& module) {
|
||||
QMutexLocker locker(&mutex_); // 确保线程安全
|
||||
if (j.is_array()) {
|
||||
QVariantList list;
|
||||
for (const auto& el : j) list.append(jsonToVariant(el));
|
||||
return list;
|
||||
}
|
||||
|
||||
if (j.is_object()) {
|
||||
QVariantMap map;
|
||||
for (auto it = j.begin(); it != j.end(); ++it)
|
||||
map[QString::fromStdString(it.key())] = jsonToVariant(it.value());
|
||||
return map;
|
||||
}
|
||||
|
||||
return QVariant(); // fallback
|
||||
}
|
||||
QVariant JsonRpcClient::call(const QString& method, const QJsonArray& params, const QString& module)
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
if (socket_.state() != QAbstractSocket::ConnectedState) {
|
||||
qWarning() << "[JsonRpcClient] Socket not connected, trying to reconnect...";
|
||||
qWarning() << "[JsonRpcClient] Socket not connected.";
|
||||
if (!reconnect()) return QVariant();
|
||||
}
|
||||
|
||||
QJsonObject request{
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", method},
|
||||
{"params", params},
|
||||
{"id", idCounter_++}
|
||||
};
|
||||
QString reqStr = QString(R"({"jsonrpc":"2.0","method":"%1","params":%2,"id":%3)")
|
||||
.arg(method)
|
||||
.arg(QString::fromUtf8(QJsonDocument(params).toJson(QJsonDocument::Compact)))
|
||||
.arg(idCounter_++);
|
||||
if (!module.isEmpty()) {
|
||||
request["module"] = module;
|
||||
reqStr += QString(R"(,"module":"%1")").arg(module);
|
||||
}
|
||||
reqStr += "}";
|
||||
|
||||
QJsonDocument doc(request);
|
||||
QByteArray data = doc.toJson(QJsonDocument::Compact);
|
||||
|
||||
if (socket_.write(data) == -1 || !socket_.waitForBytesWritten(1000)) {
|
||||
qWarning() << "[JsonRpcClient] Write failed:" << socket_.errorString();
|
||||
if (socket_.write(reqStr.toUtf8()) == -1 || !socket_.waitForBytesWritten(1000)) {
|
||||
qWarning() << "[JsonRpcClient] Write failed.";
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (!socket_.waitForReadyRead(3000)) {
|
||||
qWarning() << "[JsonRpcClient] No response received:" << socket_.errorString();
|
||||
if (!socket_.waitForReadyRead(10000)) {
|
||||
qWarning() << "[JsonRpcClient] Read timeout.";
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QByteArray responseData = socket_.readAll();
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument respDoc = QJsonDocument::fromJson(responseData, &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "[JsonRpcClient] JSON parse error:" << parseError.errorString();
|
||||
// 使用 nlohmann json 替代 Qt 解析
|
||||
try {
|
||||
auto respJson = nlohmann::json::parse(responseData.constData(), responseData.constData() + responseData.size());
|
||||
|
||||
if (respJson.contains("error")) {
|
||||
qWarning() << "[JsonRpcClient] Error:" << QString::fromStdString(respJson["error"].dump());
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return jsonToVariant(respJson["result"]);
|
||||
}
|
||||
catch (const nlohmann::json::parse_error& e) {
|
||||
qWarning() << "[JsonRpcClient] Parse error:" << e.what();
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
QByteArray JsonRpcClient::finsReadCall(const QString& method, const QString& params, const QString& module) {
|
||||
QMutexLocker locker(&mutex_);
|
||||
if (socket_.state() != QAbstractSocket::ConnectedState) {
|
||||
qWarning() << "[JsonRpcClient] Socket not connected.";
|
||||
if (!reconnect()) return QByteArray();
|
||||
}
|
||||
|
||||
QJsonObject resp = respDoc.object();
|
||||
if (resp.contains("error")) {
|
||||
qWarning() << "[JsonRpcClient] JSON-RPC error:" << resp["error"];
|
||||
return QVariant();
|
||||
QString reqStr = QString(R"({"jsonrpc":"2.0","method":"%1","params":["%2"],"id":%3)")
|
||||
.arg(method)
|
||||
.arg(params)
|
||||
.arg(idCounter_++);
|
||||
if (!module.isEmpty()) {
|
||||
reqStr += QString(R"(,"module":"%1")").arg(module);
|
||||
}
|
||||
reqStr += "}";
|
||||
|
||||
if (socket_.write(reqStr.toUtf8()) == -1 || !socket_.waitForBytesWritten(1000)) {
|
||||
qWarning() << "[JsonRpcClient] Write failed.";
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (!socket_.waitForReadyRead(10000)) {
|
||||
qWarning() << "[JsonRpcClient] Read timeout.";
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray responseData = socket_.readAll();
|
||||
|
||||
// 使用 nlohmann json 替代 Qt 解析
|
||||
try {
|
||||
if (responseData.contains("error")) {
|
||||
//qWarning() << "[JsonRpcClient] Error:" << QString::fromStdString(respJson["error"].dump());
|
||||
return QByteArray();
|
||||
}
|
||||
int startPos = responseData.indexOf(": [") + 3;
|
||||
int length = responseData.indexOf("],") - startPos;
|
||||
auto splitResult = responseData.mid(startPos, length);
|
||||
QByteArray result;
|
||||
for (int i = 0; i < splitResult.size(); i+=3) {
|
||||
result.append(splitResult[i] -48);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (const nlohmann::json::parse_error& e) {
|
||||
qWarning() << "[JsonRpcClient] Parse error:" << e.what();
|
||||
return QByteArray();
|
||||
}
|
||||
return resp["result"].toVariant();
|
||||
}
|
||||
void JsonRpcClient::writeCall(const QString& method, const QJsonArray& params, const QString& module) {
|
||||
if (socket_.state() != QAbstractSocket::ConnectedState) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <QHostAddress>
|
||||
#include <qmap.h>
|
||||
#include <qthread.h>
|
||||
#include <nlohmannJson.hpp>
|
||||
enum connectionStatus {
|
||||
None,
|
||||
Disconnected,
|
||||
@@ -32,6 +33,7 @@ public:
|
||||
JsonRpcClient(const QString& host = "127.0.0.1", quint16 port = 9000);
|
||||
void writeCall(const QString& method, const QJsonArray& params = {}, const QString& module = QString());
|
||||
QVariant call(const QString& method, const QJsonArray& params = {}, const QString& module = QString());
|
||||
QByteArray finsReadCall(const QString& method, const QString& params = "", const QString& module = QString());
|
||||
bool reconnect(); // 主动重连,或 call() 失败时调用
|
||||
private:
|
||||
|
||||
|
||||
@@ -5,22 +5,6 @@
|
||||
typedef dsModuleBase* (*CreateFunction)();
|
||||
typedef void (*ReleaseFunction)(dsModuleBase* animal);
|
||||
|
||||
struct correctionStruct
|
||||
{
|
||||
std::vector<double> in_X_X0Y;
|
||||
std::vector<double> in_Y_X0Y;
|
||||
std::vector<double> in_Z_X0Y;
|
||||
std::vector<double> in_Z_X0Y_Value;
|
||||
std::vector<double> in_X_X0Z;
|
||||
std::vector<double> in_Y_X0Z;;
|
||||
std::vector<double> in_Z_X0Z;
|
||||
std::vector<double> in_Y_X0Z_Value;
|
||||
std::vector<double> in_X_Y0Z;
|
||||
std::vector<double> in_Y_Y0Z;
|
||||
std::vector<double> in_Z_Y0Z;
|
||||
std::vector<double> in_X_Y0Z_Value;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
QString m_stationKy;
|
||||
QString key; // 相机名称
|
||||
|
||||
+30
-25
@@ -8,7 +8,10 @@
|
||||
#include <handleAiModel.h>
|
||||
#include <summaryData.h>
|
||||
#include <quuid.h>
|
||||
|
||||
enum saveMode {
|
||||
basic,
|
||||
oneFile
|
||||
};
|
||||
//所有检测需要的数据均放在这里
|
||||
class camera;
|
||||
class detData;
|
||||
@@ -16,8 +19,7 @@ class detDataManager;
|
||||
class triggerManager;
|
||||
using resultHandleCallback = std::function<void(std::shared_ptr <detData>)>;
|
||||
using algoEvaluateCallback = std::function<bool(std::shared_ptr <detData>,handleAiModelManager*)>;
|
||||
class detData
|
||||
{
|
||||
class detData{
|
||||
public:
|
||||
|
||||
|
||||
@@ -48,6 +50,8 @@ public:
|
||||
triggerManager* triggerPtr = nullptr;//触发器指针 一般为plc模块指针
|
||||
#pragma endregion
|
||||
#pragma region 存图相关
|
||||
saveMode _saveMode = saveMode::basic;
|
||||
QString saveObjectName = "";//存图项目名 用于与其他检测项目区分开
|
||||
QMutex resultMutex;//结果图锁
|
||||
std::vector<cv::Mat> resultImgs;//结果图容器
|
||||
std::vector<cv::Mat> segOriginImgs;//seg检测原图容器
|
||||
@@ -57,12 +61,14 @@ public:
|
||||
std::vector<cv::Mat> oriImgs;//原图容器
|
||||
std::vector<std::string> oriFormat;//原图格式 如果数量不一致直接全存bmp
|
||||
std::vector<std::string> imgSaveNameParameter;//命名规则 str1_str2... 第一个参数已默认为相机名,在构造函数
|
||||
void customSaveParam(QString saveObjectNameIN, saveMode _saveModeIN, std::vector<std::string> imgSaveNameParameterIN) {
|
||||
saveObjectName = saveObjectNameIN;
|
||||
_saveMode = _saveModeIN;
|
||||
imgSaveNameParameter.insert(imgSaveNameParameter.end(),imgSaveNameParameterIN.begin(), imgSaveNameParameterIN.end());
|
||||
}
|
||||
#pragma endregion
|
||||
QMap<QString, QVariant> additional;
|
||||
detData(std::string IN_cameraKeyName) {
|
||||
cameraKeyName = IN_cameraKeyName;
|
||||
imgSaveNameParameter.push_back(cameraKeyName);
|
||||
}
|
||||
detData() {}
|
||||
~detData() {
|
||||
for (auto& img : oriImgs)
|
||||
img.release();
|
||||
@@ -74,8 +80,7 @@ public:
|
||||
img.second.release();
|
||||
}
|
||||
};
|
||||
class detDataManager
|
||||
{
|
||||
class detDataManager{
|
||||
public:
|
||||
detDataManager(triggerManager* in_triggerManager)
|
||||
:_triggerManager(in_triggerManager){
|
||||
@@ -84,18 +89,14 @@ public:
|
||||
std::unordered_map<QString, std::shared_ptr<detData>>map;
|
||||
QMutex dataMutex;
|
||||
|
||||
std::shared_ptr <detData> createDetData(
|
||||
QString IN_cameraKeyName,
|
||||
std::string IN_SN,int imgAmountMin,
|
||||
std::vector<std::string> oriFormat){
|
||||
|
||||
std::shared_ptr <detData> createDetData(QString IN_cameraKeyName,std::string IN_SN, int imgAmountMin,std::vector<std::string> oriFormat) {
|
||||
QMutexLocker locker(&dataMutex);
|
||||
std::shared_ptr <detData>dataPtr(new detData(IN_cameraKeyName.toStdString()));
|
||||
std::shared_ptr <detData>dataPtr(new detData());
|
||||
dataPtr->cameraKeyName = IN_cameraKeyName.toStdString();
|
||||
dataPtr->imgSaveNameParameter.push_back(IN_cameraKeyName.toStdString());
|
||||
dataPtr->oriFormat = oriFormat;
|
||||
dataPtr->triggerPtr = _triggerManager;
|
||||
dataPtr->SNcode = IN_SN;
|
||||
//dataPtr->registerResultHandleCallback(resultSolver);
|
||||
//dataPtr->registerAlgoEvaluateCallback(_algoEvaluateCallback);
|
||||
dataPtr->imgAmountMin = imgAmountMin;
|
||||
dataPtr->dManager = this;
|
||||
|
||||
@@ -105,22 +106,26 @@ public:
|
||||
qDebug() << "创建新容器失败";
|
||||
return dataPtr;
|
||||
}
|
||||
std::shared_ptr <detData> getDetData(QString uuid)
|
||||
{
|
||||
std::shared_ptr <detData> createDetData() {
|
||||
QMutexLocker locker(&dataMutex);
|
||||
std::shared_ptr <detData>dataPtr(new detData());
|
||||
map.insert({ dataPtr->uuid,dataPtr });
|
||||
if (dataPtr == nullptr)
|
||||
qDebug() << "创建新容器失败";
|
||||
return dataPtr;
|
||||
}
|
||||
std::shared_ptr <detData> getDetData(QString uuid){
|
||||
QMutexLocker locker(&dataMutex);
|
||||
auto it = map.find(uuid);
|
||||
if (it != map.end())
|
||||
{
|
||||
if (it != map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
bool deleteDetData(QString uuid)
|
||||
{
|
||||
bool deleteDetData(QString uuid) {
|
||||
QMutexLocker locker(&dataMutex);
|
||||
auto it = map.find(uuid);
|
||||
if (it != map.end())
|
||||
{
|
||||
if (it != map.end()) {
|
||||
map.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <qdatetime.h>
|
||||
#include <backStruct.h>
|
||||
#include <detData.h>
|
||||
#define saveImgEnable 1
|
||||
|
||||
enum imgSaveThreadType
|
||||
{
|
||||
oriImg,
|
||||
@@ -107,55 +107,48 @@ public:
|
||||
path = pathIn;
|
||||
}
|
||||
imgSaveThread saveThread;
|
||||
QString genDirName(std::shared_ptr <detData> data, imgSaveThreadType type) {
|
||||
//sqlTableDatas sqlRes = sql->selectSingleData("saveHour", data->SNcode);//查找之前的数据
|
||||
//获取关键数据
|
||||
QString imgSaveDirStr = path;//所有图片的路径 sample "D://CCD"
|
||||
QString imgTypeDirStr;//二级目录,图片类型决定 sample "Result"
|
||||
QString dateDirStr;//三级目录,日期决定 sample"2024-6-8"
|
||||
QString hourDirStr;//四级目录,小时段决定 sample "14H"
|
||||
QString okNgStr;//五级目录,OK/NG决定 sample "OK"
|
||||
QString detailNameStr;//六级目录 主要是SN,如没有sn则可能是相机名称
|
||||
#pragma region 赋值
|
||||
//imgTypeDirStr
|
||||
switch (type)
|
||||
{
|
||||
case oriImg:
|
||||
imgTypeDirStr = "原图";
|
||||
break;
|
||||
case resImg:
|
||||
imgTypeDirStr = "结果图";
|
||||
break;
|
||||
default:
|
||||
imgTypeDirStr = "error";
|
||||
}
|
||||
QString genDirName(std::shared_ptr<detData> data, imgSaveThreadType type, saveMode mode){
|
||||
// 一级目录(根路径)
|
||||
const QString basePath = path;
|
||||
|
||||
// 二级目录(图片类型)
|
||||
static const QMap<imgSaveThreadType, QString> typeMap{
|
||||
{ oriImg, "原图" },
|
||||
{ resImg, "结果图" }
|
||||
};
|
||||
QString imgTypeDir = typeMap.value(type, "error");
|
||||
|
||||
// 日期与小时
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QString dateDir = now.toString("yyyy-MM-dd");
|
||||
QString hourDir = QString("%1H").arg(now.time().hour());
|
||||
|
||||
// 检测结果
|
||||
QString resultDir;
|
||||
if (!data->aiDetOK && !data->halconOK) resultDir = "NG";
|
||||
else if (!data->aiDetOK) resultDir = "aiNG";
|
||||
else if (!data->halconOK) resultDir = "halconNG";
|
||||
else resultDir = "OK";
|
||||
|
||||
if (mode == oneFile) {
|
||||
|
||||
|
||||
{
|
||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
dateDirStr = currentDateTime.toString("yyyy-MM-dd");
|
||||
hourDirStr = QString::number(currentDateTime.time().hour()) + "H//";
|
||||
}
|
||||
if(data->aiDetOK == false && data->halconOK == false)
|
||||
okNgStr = "NG";
|
||||
else if (data->aiDetOK == false)
|
||||
okNgStr = "aiNG";
|
||||
else if (data->halconOK == false)
|
||||
okNgStr = "halconNG";
|
||||
else
|
||||
okNgStr = "OK";
|
||||
//detailNameStr
|
||||
if (data->SNcode.length() != 0 && data->SNcode.length() < 50)
|
||||
detailNameStr = QString::fromStdString(data->SNcode);
|
||||
else
|
||||
detailNameStr = QString::fromStdString(data->cameraKeyName);
|
||||
#pragma endregion
|
||||
return QString(imgSaveDirStr + "/" +
|
||||
imgTypeDirStr + "/" +
|
||||
dateDirStr + "/" +
|
||||
hourDirStr + "/" +
|
||||
okNgStr + "/" +
|
||||
detailNameStr + "/");
|
||||
// SN 或相机名
|
||||
QString detailName = (data->SNcode.size() > 0 && data->SNcode.size() < 50)
|
||||
? QString::fromStdString(data->SNcode)
|
||||
: QString::fromStdString(data->cameraKeyName);
|
||||
|
||||
// 拼接路径
|
||||
QDir dir(basePath);
|
||||
dir = QDir(dir.filePath(imgTypeDir));
|
||||
dir = QDir(dir.filePath(dateDir));
|
||||
dir = QDir(dir.filePath(hourDir));
|
||||
dir = QDir(dir.filePath(resultDir));
|
||||
dir = QDir(dir.filePath(detailName));
|
||||
return dir.path() + "/";
|
||||
}
|
||||
|
||||
std::vector<std::string> genFileNames(std::shared_ptr <detData> data, imgSaveThreadType type, std::string format = "")
|
||||
{
|
||||
std::vector<std::string> resultFileNames;
|
||||
@@ -193,9 +186,8 @@ public:
|
||||
return resultFileNames;
|
||||
}
|
||||
|
||||
void saveOri(std::shared_ptr <detData> data)
|
||||
{
|
||||
QString fileSavePath = genDirName(data, oriImg);//获取文件夹名
|
||||
void saveOri(std::shared_ptr <detData> data) {
|
||||
QString fileSavePath = genDirName(data, oriImg, data->_saveMode);//获取文件夹名
|
||||
createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建
|
||||
std::vector<std::string>fileNames = genFileNames(data, oriImg);
|
||||
|
||||
@@ -205,9 +197,8 @@ public:
|
||||
if (queueSize > 10)
|
||||
qDebug() << "queueSize " << queueSize;
|
||||
}
|
||||
void saveRes(std::shared_ptr <detData> data)
|
||||
{
|
||||
QString fileSavePath = genDirName(data, resImg);//获取文件夹名
|
||||
void saveRes(std::shared_ptr <detData> data){
|
||||
QString fileSavePath = genDirName(data, resImg,data->_saveMode);//获取文件夹名
|
||||
createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建
|
||||
//结果图保存
|
||||
std::vector<std::string>resFileNames = genFileNames(data, resImg);
|
||||
|
||||
@@ -25,6 +25,8 @@ triggerManager::triggerManager(detProcess* _detProcessIn, qtFuncBridge* bridgeIn
|
||||
|
||||
triggerFileName = QString::fromStdString(triggerJson["moduleName"]);
|
||||
IpAndPort = QString::fromStdString(triggerJson["initStr"]);
|
||||
heartBeatIntervalMS = triggerJson["heartBeatIntervalMS"];
|
||||
sleepIntervalMS = triggerJson["sleepIntervalMS"];
|
||||
std::vector<std::string> heartbeats = triggerJson["heartBeatCmd"];
|
||||
for (auto& cmd : heartbeats) {
|
||||
heartBeatCmds.push_back(QString::fromStdString(cmd));
|
||||
@@ -34,18 +36,16 @@ void triggerManager::run(){
|
||||
if(connectHost() == false)
|
||||
return;
|
||||
QThread::msleep(1000);
|
||||
int cnt = 0;
|
||||
QElapsedTimer heartTimer;
|
||||
while (runFlag){
|
||||
reciveCommond();
|
||||
QThread::msleep(10);
|
||||
QThread::msleep(sleepIntervalMS);
|
||||
//心跳
|
||||
cnt++;
|
||||
if (cnt > 100) {
|
||||
if (heartTimer.elapsed()> heartBeatIntervalMS) {
|
||||
sendFinsMsg(heartBeatCmds[heartBeatCmdCnt++]);
|
||||
if(heartBeatCmdCnt >= heartBeatCmds.size())
|
||||
heartBeatCmdCnt = 0;
|
||||
cnt = 0;
|
||||
// qDebug() << "heartbeat";
|
||||
heartTimer.start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -133,8 +133,23 @@ void triggerManager::decodeCameraCMD(readAllStruct& _struct, QByteArray byte)
|
||||
{
|
||||
if (byte.isEmpty())
|
||||
{
|
||||
qCritical() << "ERROR:cant read data from Fins,无法从fins读取数据";
|
||||
if (isConnected == true) {
|
||||
lostConnectionCountTimer.start();
|
||||
std::cout<< "与PLC的连接已断开,正在尝试重连" << std::endl;
|
||||
}
|
||||
if (lostConnectionRePrintTimer.elapsed() > 1000) {
|
||||
qCritical() << "ERROR:cant read data from Fins,无法从fins读取数据";
|
||||
emit bridge->setPlcConnectionError();
|
||||
isConnected = false;
|
||||
lostConnectionRePrintTimer.start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (isConnected == false) {
|
||||
emit bridge->setPlcConnectionOk();
|
||||
isConnected = true;
|
||||
qDebug() << "掉线时间:" << lostConnectionCountTimer.elapsed() / 1000.0 << "秒";
|
||||
std::cout << "重连成功,经过时间:" << lostConnectionCountTimer.elapsed() / 1000.0 << "秒" << std::endl;
|
||||
}
|
||||
checkCallbackAndTrigger(_struct,byte);
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <functional>
|
||||
#include <serviceModule.h>
|
||||
#include <nlohmannJson.hpp>
|
||||
#include <qelapsedtimer.h>
|
||||
|
||||
#define switchToRpc 1
|
||||
#define debugTesting 0
|
||||
@@ -19,33 +20,32 @@ class detProcess;
|
||||
//防止重复触发
|
||||
class triggerLockerT {
|
||||
public:
|
||||
triggerLockerT() {}
|
||||
~triggerLockerT() {
|
||||
lockerList.clear();
|
||||
// 不存在则返回true
|
||||
bool checkLocker(int pos) const {
|
||||
return lockerVec.find(pos) == lockerVec.end();
|
||||
}
|
||||
bool checkLocker(int pos) {
|
||||
for (auto& it : lockerList) {
|
||||
if (it == pos) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void reFreshLocker(QByteArray& input) {
|
||||
if (input.size() == 0)return;
|
||||
for (auto& it : lockerList) {
|
||||
if (input.at(it) == 0) {
|
||||
lockerList.erase(std::remove(lockerList.begin(), lockerList.end(), it), lockerList.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
void adddLocker(int pos) {
|
||||
lockerList.push_back(pos);
|
||||
}
|
||||
std::vector<int>lockerList;
|
||||
private:
|
||||
|
||||
// 如果和加锁的值不同则删除
|
||||
void reFreshLocker(const QByteArray& input) {
|
||||
for (auto it = lockerVec.begin(); it != lockerVec.end(); ) {
|
||||
if (it->first >= input.size() || input.at(it->first) != it->second) {
|
||||
it = lockerVec.erase(it); // erase 返回下一个迭代器
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加锁
|
||||
void addLocker(int pos, int val) {
|
||||
lockerVec[pos] = val;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<int, int> lockerVec;
|
||||
};
|
||||
|
||||
//触发器类 fins触发 tcp触发等 替代myiothread
|
||||
class triggerManager : public serviceModule
|
||||
{
|
||||
@@ -61,8 +61,7 @@ public:
|
||||
QString triggerFileName;
|
||||
QString IpAndPort;
|
||||
QString triggerInitStr;
|
||||
~triggerManager()
|
||||
{
|
||||
~triggerManager(){
|
||||
runFlag = false;
|
||||
this->stop();
|
||||
this->terminate();
|
||||
@@ -71,8 +70,7 @@ public:
|
||||
triggerManager(detProcess*, qtFuncBridge* bridgeIn, nlohmann::ordered_json& triggerJson);
|
||||
bool connectHost();
|
||||
void run();
|
||||
void stop()
|
||||
{
|
||||
void stop(){
|
||||
runFlag = false;
|
||||
this->terminate();
|
||||
}
|
||||
@@ -206,15 +204,13 @@ public:
|
||||
#pragma endregion
|
||||
|
||||
//CALL BACK
|
||||
struct triggerCallbackStruct
|
||||
{
|
||||
struct triggerCallbackStruct{
|
||||
int triggerAddress;
|
||||
int triggerValue;
|
||||
triggerCallback func;
|
||||
std::string funcName;
|
||||
};
|
||||
bool registerCallback(int triggerAddress, int triggerValue, triggerCallback func, std::string funcName ="")
|
||||
{
|
||||
bool registerCallback(int triggerAddress, int triggerValue, triggerCallback func, std::string funcName =""){
|
||||
triggerCallbackStruct _triggerCallbackStruct;
|
||||
_triggerCallbackStruct.triggerAddress = triggerAddress;
|
||||
_triggerCallbackStruct.triggerValue = triggerValue;
|
||||
@@ -230,8 +226,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
std::map<QByteArray, std::vector<triggerCallbackStruct>> triggerCallbackFuncs;
|
||||
void checkCallbackAndTrigger(readAllStruct& _struct,QByteArray & byteArray)//检查是否符合回调函数的触发条件
|
||||
{
|
||||
void checkCallbackAndTrigger(readAllStruct& _struct,QByteArray & byteArray){//检查是否符合回调函数的触发条件
|
||||
for (auto callback : triggerCallbackFuncs[_struct.readAllCmd])
|
||||
{
|
||||
if (checkTrigger(callback.triggerAddress, callback.triggerValue, _struct, byteArray) == true)
|
||||
@@ -249,8 +244,7 @@ public:
|
||||
}
|
||||
}
|
||||
std::string readSnFromQByteArray(QByteArray plcByte, int dmPos,
|
||||
bool highLowConversion, bool clearAfterRead, int Size)
|
||||
{
|
||||
bool highLowConversion, bool clearAfterRead, int Size){
|
||||
int startPos = 0;
|
||||
for (auto& _struct : readAllCmds) {
|
||||
if (dmPos > _struct.startPos &&
|
||||
@@ -262,8 +256,7 @@ public:
|
||||
return "ERROR_OUT_OF_RANGE";
|
||||
}
|
||||
int triggerPos = (dmPos - startPos) * 2;
|
||||
if (triggerPos < 0)
|
||||
{
|
||||
if (triggerPos < 0){
|
||||
std::cout << "Read SN error,trigger is DM:" << dmPos << ",but read start at DM:" << startPos << endl;
|
||||
return "snErrorsnError" + getCurrentDateTime();
|
||||
}
|
||||
@@ -271,20 +264,16 @@ public:
|
||||
if (plcByte.at(triggerPos + 1) == 0 && plcByte.at(triggerPos) == 0)
|
||||
return "snErrorsnError" + getCurrentDateTime();
|
||||
int snCount = 0;
|
||||
if (highLowConversion == true)
|
||||
{
|
||||
while (plcByte.at(snCount + triggerPos) != 0 || plcByte.at(snCount + triggerPos + 1) != 0)
|
||||
{
|
||||
if (highLowConversion == true){
|
||||
while (plcByte.at(snCount + triggerPos) != 0 || plcByte.at(snCount + triggerPos + 1) != 0){
|
||||
|
||||
if (plcByte.at(snCount + triggerPos) != 0)
|
||||
str += QChar(plcByte.at(snCount + triggerPos));
|
||||
snCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (plcByte.at(snCount + triggerPos) != 0 || plcByte.at(snCount + triggerPos + 1) != 0)
|
||||
{
|
||||
else{
|
||||
while (plcByte.at(snCount + triggerPos) != 0 || plcByte.at(snCount + triggerPos + 1) != 0){
|
||||
|
||||
if (plcByte.at(snCount + triggerPos + 1) != 0)
|
||||
str += QChar(plcByte.at(snCount + triggerPos + 1));
|
||||
@@ -303,6 +292,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
QElapsedTimer lostConnectionCountTimer,lostConnectionRePrintTimer;
|
||||
qtFuncBridge* bridge;
|
||||
bool libLoadedflag = false;
|
||||
QLibrary* m_lib = nullptr;
|
||||
@@ -319,25 +309,34 @@ private:
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="byte">QByteArray</param>
|
||||
/// <returns></returns>
|
||||
bool checkTrigger(int dmPos, int value, readAllStruct& _struct, QByteArray& byte, bool lockerDisable = false)
|
||||
{
|
||||
bool checkTrigger(int dmPos, int value, readAllStruct& _struct, QByteArray& byte, bool lockerDisable = false){
|
||||
int triggerPos = (dmPos - _struct.startPos) * 2 + 1;
|
||||
if (byte.size() < triggerPos)
|
||||
return false;
|
||||
if (byte.at(triggerPos) == value)
|
||||
{
|
||||
if (byte.at(triggerPos) == value){
|
||||
if (tLocker[_struct.readAllCmd].checkLocker(triggerPos) == false)
|
||||
return false;
|
||||
if (lockerDisable == false)
|
||||
tLocker[_struct.readAllCmd].adddLocker(triggerPos);
|
||||
tLocker[_struct.readAllCmd].addLocker(triggerPos, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
bool checkTrigger_Unsafe(int dmPos, int value, readAllStruct& _struct, QByteArray& byte, bool lockerDisable = false) {
|
||||
int triggerPos = (dmPos - _struct.startPos) * 2 + 1;
|
||||
if (byte.at(triggerPos) == value) {
|
||||
if (tLocker[_struct.readAllCmd].checkLocker(triggerPos) == false)
|
||||
return false;
|
||||
if (lockerDisable == false)
|
||||
tLocker[_struct.readAllCmd].addLocker(triggerPos, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
//接受数据
|
||||
bool reciveFinsMsg(QByteArray& readByte)
|
||||
{
|
||||
bool reciveFinsMsg(QByteArray& readByte){
|
||||
if (!trigger->readData(vec_mat, readByte))
|
||||
{
|
||||
qCritical() << "[TCP] " << " finstcp_ptr readData error!";
|
||||
@@ -349,7 +348,8 @@ private:
|
||||
//解析并触发
|
||||
void decodeCameraCMD(readAllStruct&,QByteArray byte);
|
||||
//触发器的配置
|
||||
int interval = 50;//间隔
|
||||
int sleepIntervalMS = 50;//间隔
|
||||
int heartBeatIntervalMS = 800;
|
||||
int heartBeatCmdCnt = 0;
|
||||
std::vector<QString> heartBeatCmds;
|
||||
#if switchToRpc==0
|
||||
@@ -359,6 +359,7 @@ private:
|
||||
ReleaseRpcModuleBaseFunction destory_finstcp; //释放
|
||||
rpcModuleBase* trigger = nullptr;
|
||||
#endif
|
||||
bool isConnected = true;
|
||||
bool runFlag = true;
|
||||
bool init = false;
|
||||
std::vector<cv::Mat> vec_mat;//没啥用,一直保持为空就好
|
||||
|
||||
@@ -28,6 +28,9 @@ public:
|
||||
SQLiteDB* getDatabase() {
|
||||
return _detProcess->dataBase;
|
||||
}
|
||||
bool excuteCliCommandPreset(const QString& uuid) {
|
||||
return _detProcess->_cliManager->excutePreset(uuid);
|
||||
}
|
||||
private:
|
||||
bool initOnce = false;
|
||||
detProcess* _detProcess;
|
||||
|
||||
@@ -11,9 +11,10 @@ public:
|
||||
CsvWriter* _csvWriter = nullptr;
|
||||
missonResultHandle* _missonResultHandle = nullptr;
|
||||
ServiceManager _serviceManager;
|
||||
CLIManager* _cliManager; // 命令行接口管理器
|
||||
bool initOnce = false;
|
||||
detProcess():_cliManager(&_serviceManager){
|
||||
dataBase = new SQLiteDB("./DataBase/", "eui_db");
|
||||
detProcess(){
|
||||
dataBase = new SQLiteDB("./sqlDatabse/", "eui_db");
|
||||
_csvWriter = new CsvWriter(dataBase);
|
||||
}
|
||||
|
||||
@@ -33,6 +34,7 @@ public:
|
||||
_serviceManager._csvWriter = _csvWriter;
|
||||
_serviceManager._handleAiModelManager = new handleAiModelManager(jsonIn, bridgeIn);
|
||||
connect(bridgeIn, &qtFuncBridge::reInitConfig, this, [=]() {reinitConfig(); });
|
||||
_cliManager = new CLIManager(&_serviceManager, bridgeIn);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -88,6 +90,7 @@ public:
|
||||
json["missionSettings"],
|
||||
dataBase, bridge
|
||||
);
|
||||
_cliManager->initBasicPreset();
|
||||
//_threadManager->registerResultHandleCallback(
|
||||
// [this](std::shared_ptr<detData> data) {
|
||||
// detectionResultHandle(data);
|
||||
@@ -110,7 +113,7 @@ private:
|
||||
nlohmann::ordered_json json;
|
||||
qtFuncBridge* bridge;
|
||||
MissionLoader _missionLoader; // 任务加载器,用于加载任务配置
|
||||
CLIManager _cliManager; // 命令行接口管理器
|
||||
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
+118
-66
@@ -23,79 +23,131 @@ private:
|
||||
|
||||
class CLIManager {
|
||||
public:
|
||||
CLIManager(ServiceManager* _serviceManagerIn):_serviceManager(_serviceManagerIn){}
|
||||
CLIManager(ServiceManager* _serviceManagerIn,qtFuncBridge* bridgeIn)
|
||||
:_serviceManager(_serviceManagerIn), bridge(bridgeIn) {}
|
||||
~CLIManager() {}
|
||||
|
||||
void cliCommands(const std::string& command,std::vector<QVariant>args) {
|
||||
auto it = commandMap.find(command);
|
||||
if (it != commandMap.end()) {
|
||||
switch (it->second) {
|
||||
case Trigger:
|
||||
trigger(args);
|
||||
break;
|
||||
case Evaluate:
|
||||
evaluate(args);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
#pragma region trash
|
||||
// void cliCommands(const std::string& command,std::vector<QVariant>args) {
|
||||
// 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<QVariant>&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<QVariant>&args) {
|
||||
//#pragma region 处理错误
|
||||
// //if()
|
||||
//#pragma endregion
|
||||
//
|
||||
// }
|
||||
#pragma endregion
|
||||
bool cliCommand(const QString& command) {
|
||||
auto strList = command.split("#");
|
||||
if (strList[0] == "fins") {
|
||||
_serviceManager->_triggerManager->sendFinsMsg(strList[1]);
|
||||
return true;
|
||||
}
|
||||
else if (strList[0] == "reconfig") {
|
||||
return true;
|
||||
}
|
||||
else if (strList[0] == "waitMs") {
|
||||
QThread::msleep(strList[1].toInt());
|
||||
return true;
|
||||
}
|
||||
std::cout << "命令未定义!" << command.toStdString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
bool excutePreset(const QString& uuid) {
|
||||
auto commands = presets[uuid];
|
||||
std::thread([this,commands] {for (auto& command : commands)cliCommand(command); }).detach();
|
||||
return true;
|
||||
}
|
||||
void addPreset(const QString& btnName, QStringList commands) {
|
||||
presets[btnName] = commands;
|
||||
|
||||
}
|
||||
void initBasicPreset() {
|
||||
for (auto& data : _serviceManager->_triggerManager->triggerCallbackFuncs) {
|
||||
for (auto& callbacks : data.second) {
|
||||
QString uuid = QUuid::createUuid().toString();;
|
||||
auto commands = basicTriggerPresetGenerate(callbacks.triggerAddress);
|
||||
QString tips;
|
||||
for(auto& cmd : commands) {
|
||||
tips += cmd + "\n";
|
||||
}
|
||||
emit bridge->runCommand_addBtn(
|
||||
QString::fromStdString(callbacks.funcName),tips,uuid);
|
||||
presets[uuid] = commands;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Unknown command: " << command << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void trigger(std::vector<QVariant>&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<QVariant>&args) {
|
||||
#pragma region 处理错误
|
||||
//if()
|
||||
#pragma endregion
|
||||
|
||||
QStringList basicTriggerPresetGenerate(int& triggerAddress) {
|
||||
QString triggerAddressStr = QString::number(triggerAddress);
|
||||
return {
|
||||
"fins#write_short_"+ triggerAddressStr +"_1",
|
||||
"waitMs#500",
|
||||
"fins#write_short_" + triggerAddressStr + "_0",
|
||||
};
|
||||
}
|
||||
private:
|
||||
qtFuncBridge* bridge;
|
||||
QMap<QString, QStringList> presets;
|
||||
ServiceManager* _serviceManager;
|
||||
enum CommandType {
|
||||
Trigger,
|
||||
|
||||
Binary file not shown.
@@ -14,6 +14,7 @@
|
||||
#include <uiModule/uiModule_histogramWidget.h>
|
||||
#include <uiModule/uiModule_userSwitch.h>
|
||||
#include <uiModule/uiModule_softwareDataDisplay.h>
|
||||
#include <uiModule/uiModule_runCommand.h>
|
||||
class displayWidget :public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -29,7 +30,8 @@ public:
|
||||
dayNightShiftHistogramWidget* _dayNightShiftHistogramWidget;
|
||||
userSwitch* _userSwitch;
|
||||
softwareDataDisplay* _softwareDataDisplay;
|
||||
//uiModuleLocationMap* _uiModuleLocationMap = new uiModuleLocationMap();
|
||||
ConnectionWidget* _ConnectionWidget = new ConnectionWidget(this);
|
||||
runCommandWidget* _runCommandWidget;
|
||||
LogWindow* log = new LogWindow();
|
||||
displayWidget(appConfig* config) :m_config(config)
|
||||
{
|
||||
@@ -172,12 +174,13 @@ public:
|
||||
lineWidgetJustForShow->setFixedWidth(5);
|
||||
titleLayout->addWidget(lineWidgetJustForShow);
|
||||
QFont font3("微软雅黑", 10, QFont::Bold);
|
||||
#pragma region 日志分析按钮
|
||||
{
|
||||
QVBoxLayout* btnLayout = new QVBoxLayout();
|
||||
QPushButton* btn = new QPushButton(this);
|
||||
btn->setIcon(QIcon(":/TongYongUiIcon/TongYongUiIcon/4.LogAnalyze.png"));
|
||||
btn->setFixedSize(QSize(50, 50));
|
||||
btn->setIconSize(QSize(25, 25)); // 设置图标大小,保持等比例(根据你图标原始比例设置合适尺寸)
|
||||
btn->setIconSize(QSize(25, 25));
|
||||
btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
@@ -198,12 +201,14 @@ public:
|
||||
emit changeStackWidget(2);
|
||||
});
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma region 打开配置文件按钮
|
||||
{
|
||||
QVBoxLayout* btnLayout = new QVBoxLayout();
|
||||
QPushButton* btn = new QPushButton(this);
|
||||
btn->setIcon(QIcon(":/TongYongUiIcon/TongYongUiIcon/9.paramSetting.png"));
|
||||
btn->setFixedSize(QSize(50, 50));
|
||||
btn->setIconSize(QSize(25, 25)); // 设置图标大小,保持等比例(根据你图标原始比例设置合适尺寸)
|
||||
btn->setIconSize(QSize(25, 25));
|
||||
btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
@@ -224,11 +229,13 @@ public:
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(config->settingJsonPath)));
|
||||
});
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma region 结果图查看按钮
|
||||
{
|
||||
QVBoxLayout* btnLayout = new QVBoxLayout();
|
||||
QPushButton* btn = new QPushButton(this);
|
||||
btn->setIcon(QIcon(":/TongYongUiIcon/TongYongUiIcon/23.1.imageView.png"));
|
||||
btn->setIconSize(QSize(50, 50)); // 设置图标大小,保持等比例(根据你图标原始比例设置合适尺寸)
|
||||
btn->setIconSize(QSize(50, 50));
|
||||
btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
@@ -249,23 +256,74 @@ public:
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(config->imgSavePath)));
|
||||
});
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
#pragma region 修改检测参数按钮
|
||||
{
|
||||
QVBoxLayout* btnLayout = new QVBoxLayout();
|
||||
QPushButton* btn = new QPushButton(this);
|
||||
btn->setIcon(QIcon(":/TongYongUiIcon/TongYongUiIcon/search_1.png"));
|
||||
btn->setFixedSize(QSize(75, 50));
|
||||
btn->setIconSize(QSize(25, 25));
|
||||
btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
)");
|
||||
QLabel* text = new QLabel("修改检测参数");
|
||||
text->setFont(font3);
|
||||
text->setPalette(palette);
|
||||
btnLayout->addWidget(btn);
|
||||
btnLayout->addWidget(text);
|
||||
titleLayout->addLayout(btnLayout);
|
||||
connect(btn, &QPushButton::clicked, [=]() {
|
||||
JsonParamTableEditor* dlg = new JsonParamTableEditor(this);
|
||||
dlg->setJsonObject(m_config->settingJson["backend"]["missionSettings"]),
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
connect(dlg, &JsonParamTableEditor::jsonAccepted, [this](const nlohmann::json& result) {
|
||||
m_config->settingJson["backend"]["missionSettings"] = result;
|
||||
});
|
||||
dlg->show(); });
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma region 故障排查按钮
|
||||
{
|
||||
QVBoxLayout* btnLayout = new QVBoxLayout();
|
||||
QPushButton* btn = new QPushButton(this);
|
||||
btn->setIcon(QIcon(":/TongYongUiIcon/TongYongUiIcon/18.help.png"));
|
||||
btn->setFixedSize(QSize(50, 50));
|
||||
btn->setIconSize(QSize(25, 25));
|
||||
btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
)");
|
||||
QLabel* text = new QLabel("故障排查");
|
||||
text->setFont(font3);
|
||||
text->setPalette(palette);
|
||||
btnLayout->addWidget(btn);
|
||||
btnLayout->addWidget(text);
|
||||
titleLayout->addLayout(btnLayout);
|
||||
_runCommandWidget = new runCommandWidget();
|
||||
connect(btn, &QPushButton::clicked, [=]() {
|
||||
_runCommandWidget->show(); });
|
||||
}
|
||||
#pragma endregion
|
||||
QWidget* spacerWidget = new QWidget;
|
||||
spacerWidget->setMaximumWidth(1920);
|
||||
titleLayout->addWidget(spacerWidget, 1);
|
||||
#endif
|
||||
fancyButtonText* btn = new fancyButtonText(200, 50, u8"修改检测参数", "");
|
||||
connect(btn, &QPushButton::clicked, [=]() {
|
||||
JsonParamTableEditor* dlg = new JsonParamTableEditor(this);
|
||||
dlg->setJsonObject(m_config->settingJson["backend"]["missionSettings"]),
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
connect(dlg, &JsonParamTableEditor::jsonAccepted, [this](const nlohmann::json& result) {
|
||||
m_config->settingJson["backend"]["missionSettings"] = result;
|
||||
});
|
||||
dlg->show(); });
|
||||
|
||||
|
||||
titleLayout->addWidget(btn);
|
||||
|
||||
titleLayout->addWidget(_ConnectionWidget);
|
||||
vLayout->addWidget(titleWidget);
|
||||
|
||||
vLayout->addWidget(&_ImageWidgetManager);
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
#include <front/pages/sqlControlWidget.h>
|
||||
#include <qlabel.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qstandarditemmodel.h>
|
||||
#include <qlayout.h>
|
||||
#include <qtablewidget.h>
|
||||
#include <appCore.hpp>
|
||||
|
||||
sqliteReader::sqliteReader()
|
||||
{
|
||||
readIniFile(".//config//sqliteReader.ini");
|
||||
//_sqlManager = &_core._appConfig._sqlManager;
|
||||
//std::vector<std::string> res=_sqlManager->getTableList();
|
||||
//widgetInit(res);
|
||||
}
|
||||
|
||||
sqliteReader::~sqliteReader()
|
||||
{
|
||||
//_sqlManager.uninitlize();
|
||||
}
|
||||
void sqliteReader::widgetInit(std::vector<std::string>tables)
|
||||
{
|
||||
//1
|
||||
layout1 = new QVBoxLayout();
|
||||
this->setLayout(layout1);
|
||||
|
||||
//1-1
|
||||
QWidget* vLayout2Widget = new QWidget();
|
||||
QHBoxLayout * vLayoutt2 = new QHBoxLayout();
|
||||
vLayout2Widget->setLayout(vLayoutt2);
|
||||
layout1->addWidget(vLayout2Widget);
|
||||
|
||||
//1-1-1
|
||||
QLabel* vLayout2Label = new QLabel(u8"请选择日期");
|
||||
vLayoutt2->addWidget(vLayout2Label);
|
||||
|
||||
QComboBox * Layou2MBox = new QComboBox();
|
||||
for (auto &data : tables)
|
||||
{
|
||||
Layou2MBox->addItem(QString::fromStdString(data));
|
||||
}
|
||||
vLayoutt2->addWidget(Layou2MBox);
|
||||
connect(Layou2MBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=]() {switchWidget(Layou2MBox->currentText().toStdString()); });
|
||||
|
||||
QLabel* vLayout2Label2 = new QLabel(u8"根据SN查询");
|
||||
vLayoutt2->addWidget(vLayout2Label2);
|
||||
|
||||
QLineEdit *Layout2LEdit = new QLineEdit();
|
||||
vLayoutt2->addWidget(Layout2LEdit);
|
||||
|
||||
QPushButton* layout2QPBtn = new QPushButton(u8"查询");
|
||||
vLayoutt2->addWidget(layout2QPBtn);
|
||||
|
||||
QPushButton* dumpCsvBtn = new QPushButton(u8"导出为csv");
|
||||
vLayoutt2->addWidget(dumpCsvBtn);
|
||||
|
||||
connect(layout2QPBtn,& QPushButton::clicked, this, [=]() {searchSN(Layou2MBox->currentText().toStdString(), Layout2LEdit->text().toStdString()); });
|
||||
connect(dumpCsvBtn, &QPushButton::clicked, this, [=]() {_dumpToExcel.mainWidget->show(); });
|
||||
//1-2
|
||||
tableWidget = new QTableWidget();
|
||||
|
||||
|
||||
layout1->addWidget(tableWidget);
|
||||
switchWidget(Layou2MBox->currentText().toStdString());
|
||||
|
||||
}
|
||||
void sqliteReader::switchWidget(std::string tableName)
|
||||
{
|
||||
#if 0
|
||||
sqlTableDatas res = _sqlManager->selectAllData(tableName);
|
||||
tableWidget->clear();
|
||||
delete tableWidget;
|
||||
tableWidget = new QTableWidget();
|
||||
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
layout1->addWidget(tableWidget);
|
||||
if (res.rowDatas.size() > 0)
|
||||
{
|
||||
int colsNum = res.rowDatas[0].size() + 1 - avoidMap.size();
|
||||
tableWidget->setColumnCount(colsNum);
|
||||
//tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("SN"));
|
||||
//for (int i = 0; i < res.at(0).dataVec.size(); i++)
|
||||
//创建列名
|
||||
{
|
||||
int index = 0;
|
||||
std::unordered_map<QString, QString>::iterator it;
|
||||
std::unordered_map<QString, QString>::iterator it2;
|
||||
|
||||
for (auto&data : res.rowDatas[0])
|
||||
{
|
||||
it = avoidMap.find(QString::fromStdString(data.key));
|
||||
if (it == avoidMap.end())
|
||||
{
|
||||
QString Name = QString::fromStdString(data.key);
|
||||
it2 = cuttomName.find(Name);
|
||||
if (it2 != cuttomName.end())
|
||||
Name = it2->second;
|
||||
tableWidget->setHorizontalHeaderItem(index, new QTableWidgetItem(Name));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//tableWidget->setColumnCount(res.size());
|
||||
for (int i = 0; i < res.rowDatas.size(); i++)
|
||||
{
|
||||
//for (auto& data : res.rowDatas[0])
|
||||
{
|
||||
int row = tableWidget->rowCount();
|
||||
tableWidget->insertRow(row);
|
||||
//tableWidget->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(data.key)));
|
||||
{
|
||||
int index = 0;
|
||||
std::unordered_map<QString, QString>::iterator it;
|
||||
for (auto& data : res.rowDatas[i])
|
||||
{
|
||||
it = avoidMap.find(QString::fromStdString(data.key));
|
||||
if (it == avoidMap.end())
|
||||
{
|
||||
tableWidget->setItem(row, index, new QTableWidgetItem(QString::fromStdString(data.value)));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//tableWidget->horizontalHeader
|
||||
}
|
||||
void sqliteReader::searchSN(std::string tableName, std::string SN)
|
||||
{
|
||||
#if 0
|
||||
sqlTableDatas res = _sqlManager->selectRowData(SN);
|
||||
tableWidget->clear();
|
||||
delete tableWidget;
|
||||
tableWidget = new QTableWidget();
|
||||
layout1->addWidget(tableWidget);
|
||||
if (res.rowDatas.size()>0)//非空
|
||||
{
|
||||
tableWidget->setColumnCount(res.rowDatas[0].size() - avoidMap.size());
|
||||
//tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("SN"));
|
||||
{
|
||||
int index = 0;
|
||||
std::unordered_map<QString, QString>::iterator it;
|
||||
std::unordered_map<QString, QString>::iterator it2;
|
||||
for (auto&data : res.rowDatas[0])
|
||||
{
|
||||
it = avoidMap.find(QString::fromStdString(data.key));
|
||||
if (it == avoidMap.end())
|
||||
{
|
||||
QString Name = QString::fromStdString(data.key);
|
||||
it2 = cuttomName.find(Name);
|
||||
if (it2 != cuttomName.end())
|
||||
Name = it2->second;
|
||||
tableWidget->setHorizontalHeaderItem(index, new QTableWidgetItem(Name));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//tableWidget->setColumnCount(res.dataVec.size());
|
||||
|
||||
int row = tableWidget->rowCount();
|
||||
tableWidget->insertRow(row);
|
||||
{
|
||||
int index = 0;
|
||||
std::unordered_map<QString, QString>::iterator it;
|
||||
for (auto&data : res.rowDatas[0])
|
||||
{
|
||||
it = avoidMap.find(QString::fromStdString(data.key));
|
||||
if (it == avoidMap.end())
|
||||
{
|
||||
tableWidget->setItem(row, index, new QTableWidgetItem(QString::fromStdString(data.value)));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(res.rowDatas.size()!=0)
|
||||
{
|
||||
tableWidget->setColumnCount(res.rowDatas[0].size() + 1);
|
||||
tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("SN"));
|
||||
tableWidget->setColumnCount(1);
|
||||
}
|
||||
|
||||
int row = tableWidget->rowCount();
|
||||
tableWidget->insertRow(row);
|
||||
tableWidget->setItem(row, 0, new QTableWidgetItem(u8"找不到该数据!"));
|
||||
}
|
||||
|
||||
#endif
|
||||
//tableWidget->horizontalHeader
|
||||
}
|
||||
|
||||
bool sqliteReader::readIniFile(const QString &filePath) {
|
||||
//std::unordered_map<QString, QString> avoiData;
|
||||
//std::unordered_map<QString, QString> cutomName;
|
||||
QFile file(filePath);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&file);
|
||||
QString currentSection;
|
||||
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().trimmed();
|
||||
if (line.startsWith('[') && line.endsWith(']')) {
|
||||
// This line is a section header
|
||||
currentSection = line.mid(1, line.length() - 2);
|
||||
}
|
||||
else if (!line.isEmpty() && !line.startsWith(';') && !currentSection.isEmpty()) {
|
||||
// This line is a key-value pair within a section
|
||||
int separatorIndex = line.indexOf('=');
|
||||
if (separatorIndex != -1) {
|
||||
if (!currentSection.compare("avoid"))
|
||||
{
|
||||
QString key = line.left(separatorIndex).trimmed();
|
||||
QString value = line.mid(separatorIndex + 1).trimmed();
|
||||
if (!value.compare("true"))
|
||||
avoidMap.insert({ key, value });
|
||||
}
|
||||
else if (!currentSection.compare("customName"))
|
||||
{
|
||||
QString key = line.left(separatorIndex).trimmed();
|
||||
QString value = line.mid(separatorIndex + 1).trimmed().toUtf8();
|
||||
cuttomName.insert({ key, value });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,28 +1,140 @@
|
||||
#include <QWidget>
|
||||
#include <qlayout.h>
|
||||
#include <qtablewidget.h>
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQueryModel>
|
||||
#include <qlabel.h>
|
||||
#include <qstackedwidget.h>
|
||||
#include <uiModule/components/fancyButton.h>
|
||||
#include <uiModule/uiModule_dumpToExcel.h>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
class sqliteReader : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
sqliteReader();
|
||||
~sqliteReader();
|
||||
QVBoxLayout* layout1;
|
||||
QTableWidget* tableWidget;
|
||||
//sqlManager* _sqlManager;
|
||||
dumpToExcel _dumpToExcel;
|
||||
std::unordered_map<QString, QString>avoidMap;//不显示该数据
|
||||
std::unordered_map<QString, QString>cuttomName;//自定义列名
|
||||
void widgetInit(std::vector<std::string>tables);
|
||||
void switchWidget(std::string tableNam);
|
||||
void searchSN(std::string tableNam, std::string SN);
|
||||
bool readIniFile(const QString& filePath);
|
||||
sqliteReader() {
|
||||
QFont font("微软雅黑", 12, QFont::Bold);
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::WindowText, Qt::white);
|
||||
|
||||
//1-1
|
||||
QHBoxLayout* vLayout = new QHBoxLayout();
|
||||
layout->addLayout(vLayout);
|
||||
|
||||
//1-1-1
|
||||
QLabel* showLabel = new QLabel(u8"班次");
|
||||
showLabel->setFont(font);
|
||||
showLabel->setPalette(palette);
|
||||
vLayout->addWidget(showLabel);
|
||||
|
||||
tableSelectComboBox->setFixedWidth(150);
|
||||
vLayout->addWidget(tableSelectComboBox);
|
||||
connect(tableSelectComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, [=]() {switchWidget(tableSelectComboBox->currentText()); });
|
||||
|
||||
refreshBtn->setFont(font);
|
||||
refreshBtn->setPalette(palette);
|
||||
vLayout->addWidget(refreshBtn);
|
||||
connect(refreshBtn, &QPushButton::clicked,
|
||||
this, [=]() {refreshTable(); });
|
||||
|
||||
QLabel* showLabel2 = new QLabel(u8"SN查询");
|
||||
showLabel2->setFont(font);
|
||||
showLabel2->setPalette(palette);
|
||||
vLayout->addWidget(showLabel2);
|
||||
|
||||
QLineEdit* snInputLineEdit = new QLineEdit();
|
||||
vLayout->addWidget(snInputLineEdit);
|
||||
|
||||
vLayout->addWidget(searchSnBtn);
|
||||
connect(searchSnBtn, &QPushButton::clicked, this, [=]() {searchSN(tableSelectComboBox->currentText(), snInputLineEdit->text()); });
|
||||
|
||||
vLayout->addWidget(dumpToCsvBtn);
|
||||
connect(dumpToCsvBtn, &QPushButton::clicked, this, [=]() {dumpToCsv(tableSelectComboBox->currentText()); });
|
||||
//1-2
|
||||
layout->addWidget(tableWidget);
|
||||
}
|
||||
appConfig* _config;
|
||||
//QTableView* view = new QTableView;
|
||||
|
||||
void refreshTable() {
|
||||
tableSelectComboBox->clear();
|
||||
auto tables = _config->g_db->getTables();
|
||||
for (int i = tables.size() - 1; i > 0 ; i--){
|
||||
if (!tables[i].contains("set"))
|
||||
tableSelectComboBox->addItem(tables[i]);
|
||||
}
|
||||
}
|
||||
void switchWidget(QString tableName) {
|
||||
QSqlQueryModel* model = new QSqlQueryModel;
|
||||
model->setQuery("SELECT * from \"" + tableName + "\"");
|
||||
|
||||
if (model->lastError().isValid()) {
|
||||
qDebug() << "查询失败:" << model->lastError().text();
|
||||
return;
|
||||
}
|
||||
tableWidget->setModel(model);
|
||||
}
|
||||
void searchSN(QString tableName, QString SN) {
|
||||
// Construct SQL query to search for SN in the specified table
|
||||
QString queryStr = QString("SELECT * FROM \"%1\" WHERE 条码 = '%2'")
|
||||
.arg(tableName)
|
||||
.arg(SN);
|
||||
|
||||
QSqlQueryModel* model = new QSqlQueryModel;
|
||||
model->setQuery(queryStr);
|
||||
|
||||
if (model->lastError().isValid()) {
|
||||
qDebug() << "SN查询失败:" << model->lastError().text();
|
||||
// Optionally clear the table or show an error
|
||||
tableWidget->setModel(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
tableWidget->setModel(model);
|
||||
}
|
||||
void dumpToCsv(QString tableName) {
|
||||
// 打开文件管理器,默认文件名为表名.csv
|
||||
QString filePath = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
u8"导出为CSV",
|
||||
QDir::homePath() + "/" + tableName + ".csv",
|
||||
u8"CSV文件 (*.csv)"
|
||||
);
|
||||
|
||||
if (filePath.isEmpty()) {
|
||||
return; // 用户取消
|
||||
}
|
||||
|
||||
// 导出数据
|
||||
bool success = false;
|
||||
if (_config && _config->g_db) {
|
||||
std::mutex mutex;
|
||||
success = _config->g_db->exportTableToCSV(tableName, filePath, mutex);
|
||||
}
|
||||
|
||||
// 提示导出结果
|
||||
if (success) {
|
||||
QMessageBox::information(this, u8"导出成功", u8"数据已成功导出到:\n" + filePath);
|
||||
} else {
|
||||
QMessageBox::warning(this, u8"导出失败", u8"导出CSV文件失败,请检查路径或数据库状态。");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QComboBox* tableSelectComboBox = new QComboBox();
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QTableView* tableWidget = new QTableView();
|
||||
fancyButtonText* refreshBtn = new fancyButtonText(80, 25, u8"刷新", "");
|
||||
fancyButtonText* searchSnBtn = new fancyButtonText(80, 25, u8"查询", "");
|
||||
fancyButtonText* dumpToCsvBtn = new fancyButtonText(80, 25, u8"导出", "");
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override {
|
||||
QWidget::showEvent(event);
|
||||
refreshTable();
|
||||
}
|
||||
};
|
||||
class sqlControlWidget :public QWidget
|
||||
{
|
||||
@@ -36,8 +148,15 @@ public:
|
||||
QTableWidget* sqlWidget = new QTableWidget();
|
||||
QLabel* disconnnectedLabel = new QLabel("服务已离线");
|
||||
|
||||
sqlControlWidget()
|
||||
{
|
||||
sqlControlWidget(appConfig* _configIN){
|
||||
_sqliteReader._config = _configIN;
|
||||
this->setObjectName("sqlControlWidget");
|
||||
this->setStyleSheet(R"(
|
||||
QWidget#sqlControlWidget {
|
||||
background: rgb(50, 55, 60);
|
||||
border-radius: 10px; /* 圆角半径 */
|
||||
}
|
||||
)");
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::WindowText, Qt::white);
|
||||
QFont font("微软雅黑", 24, QFont::Bold);
|
||||
@@ -70,8 +189,8 @@ public:
|
||||
//btnLayout->addWidget(sqlWidget);
|
||||
|
||||
Layout->addLayout(btnLayout);
|
||||
|
||||
Layout->addWidget(&_sqliteReader);
|
||||
|
||||
}
|
||||
};
|
||||
#pragma once
|
||||
@@ -398,10 +398,8 @@ protected:
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
int radius = 10; // 圆角半径
|
||||
int radius = 10;
|
||||
QRect r = rect();
|
||||
|
||||
// 填充圆角背景
|
||||
painter.setBrush(QColor(50, 55, 60));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRoundedRect(r, radius, radius);
|
||||
|
||||
@@ -245,7 +245,7 @@ void MainWindow::leftBarInit(){
|
||||
registerPageBar(":/icon/icon/config.png", u8"日志", _logWidget);
|
||||
|
||||
//手动检测
|
||||
_manualDetWidget = new manualDetWidget();
|
||||
//_manualDetWidget = new manualDetWidget(m_config);
|
||||
//registerPageBar(":/icon/icon/cycleButton.png", u8"手动检测", _manualDetWidget);
|
||||
|
||||
//历史图片
|
||||
@@ -253,7 +253,7 @@ void MainWindow::leftBarInit(){
|
||||
//registerPageBar(":/icon/icon/history.png", u8"历史图片", _historyWidget);
|
||||
|
||||
//SQL
|
||||
_sqlControlWidget = new sqlControlWidget();
|
||||
_sqlControlWidget = new sqlControlWidget(config);
|
||||
registerPageBar(":/icon/icon/sql.png", u8"数据库", _sqlControlWidget);
|
||||
|
||||
//PLUGIN
|
||||
|
||||
@@ -290,7 +290,7 @@ signals:
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent* event) override
|
||||
{
|
||||
if (event->pos().y() > 35)
|
||||
if (event->pos().y() < 35)
|
||||
return
|
||||
toggleMaximize(reverse);
|
||||
QMainWindow::mouseDoubleClickEvent(event);
|
||||
|
||||
@@ -119,7 +119,6 @@ public:
|
||||
// 设置按钮显示√
|
||||
SaveBtn.setText("√");
|
||||
SaveBtn.toGreen();
|
||||
// 创建一个定时器
|
||||
QTimer::singleShot(1000, [=]() mutable {
|
||||
// 一秒后还原文本
|
||||
SaveBtn.toDefault();
|
||||
|
||||
@@ -104,5 +104,70 @@ private:
|
||||
QMutex mutex;
|
||||
int okCnt = 0, ngCnt = 0;
|
||||
};
|
||||
|
||||
class stateLabel :public QLabel {
|
||||
public:
|
||||
QPixmap okImg, errorImg;
|
||||
QTimer* timer = nullptr;
|
||||
QPixmap transparent;
|
||||
bool blink = false;
|
||||
stateLabel(QString okImgPath,QString errorImgPath, QWidget* parent = nullptr) {
|
||||
okImg = QPixmap(okImgPath).scaled(25, 25, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
errorImg = QPixmap(errorImgPath).scaled(25, 25, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
transparent = QPixmap(okImg);
|
||||
transparent.fill(Qt::transparent); // 透明图片
|
||||
this->setPixmap(okImg);
|
||||
this->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
void setOK() {
|
||||
blink = false;
|
||||
this->setPixmap(okImg);
|
||||
if (timer != nullptr) {
|
||||
delete timer;
|
||||
timer = nullptr;
|
||||
}
|
||||
}
|
||||
void setError() {
|
||||
if (!timer) {
|
||||
//this->setPixmap(errorImg);
|
||||
timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, this, [this]() mutable {
|
||||
blink = !blink;
|
||||
if (blink == false) {
|
||||
this->setPixmap(transparent);
|
||||
}
|
||||
else {
|
||||
this->setPixmap(errorImg);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!timer->isActive())
|
||||
timer->start(600);
|
||||
}
|
||||
};
|
||||
class ConnectionWidget : public QWidget {
|
||||
public:
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
stateLabel* lanConnectonLabel = new stateLabel(":/icon/icon/lan_connection_ok.png", ":/icon/icon/lan_connection_error.png",this);
|
||||
stateLabel* camConnectonLabel = new stateLabel(":/icon/icon/cam_connection_ok.png", ":/icon/icon/cam_connection_error.png", this);
|
||||
QPixmap lanConnectionOk, lanConnectionError, camConnectionOK, camConnectionError;
|
||||
QTimer* timer1 = nullptr,*timer2 = nullptr;
|
||||
QPixmap transparent1, transparent2;
|
||||
ConnectionWidget(QWidget* parent = nullptr) :
|
||||
QWidget(parent){
|
||||
layout->addWidget(lanConnectonLabel);
|
||||
layout->addWidget(camConnectonLabel);
|
||||
}
|
||||
void setPlcConnected() {
|
||||
lanConnectonLabel->setOK();
|
||||
}
|
||||
void setPlcDisconnected() {
|
||||
lanConnectonLabel->setError();
|
||||
}
|
||||
void setCamConnected() {
|
||||
camConnectonLabel->setOK();
|
||||
}
|
||||
void setCamDisconnected() {
|
||||
camConnectonLabel->setError();
|
||||
}
|
||||
};
|
||||
#pragma once
|
||||
@@ -250,7 +250,7 @@ class ImageWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QComboBox switchBox;
|
||||
QMutex switchBoxMutex;
|
||||
QMutex switchViewerMutex;
|
||||
ImageWidget(QWidget* parent = nullptr) : QWidget(parent) {
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
setObjectName("ImageWidget");
|
||||
@@ -267,23 +267,22 @@ public:
|
||||
QFont font("微软雅黑", 8 , QFont::Bold);
|
||||
QWidget* hWidget = new QWidget(this);
|
||||
QHBoxLayout* hLayout = new QHBoxLayout(hWidget);
|
||||
hWidget->setFixedHeight(15);
|
||||
#if switchToTongYongUi == 0
|
||||
hWidget->setFixedHeight(16);
|
||||
|
||||
auto spaceItem = new QSpacerItem(100, 1);
|
||||
hLayout->addSpacerItem(spaceItem);
|
||||
#endif
|
||||
|
||||
label = new QLabel(u8"相机标签");
|
||||
label->setAlignment(Qt::AlignLeft);
|
||||
label->setFont(font);
|
||||
label->setPalette(palette);
|
||||
label->setFixedHeight(10 * 2);
|
||||
label->setFixedHeight(21);
|
||||
|
||||
switchBox.setFont(font);
|
||||
switchBox.setPalette(palette);
|
||||
switchBox.setFixedHeight(21);
|
||||
switchBox.setFixedWidth(100);
|
||||
|
||||
#if switchToTongYongUi == 1
|
||||
switchBox.hide();
|
||||
#endif
|
||||
|
||||
connect(&switchBox, &QComboBox::currentTextChanged, [=](QString type)
|
||||
{
|
||||
switchViewType(type);
|
||||
@@ -333,7 +332,7 @@ public slots:
|
||||
//combobox切换槽
|
||||
void switchViewType(QString name)
|
||||
{
|
||||
QMutexLocker locker(&switchBoxMutex);
|
||||
QMutexLocker locker(&switchViewerMutex);
|
||||
auto& it = map.find(name);
|
||||
if (it == map.end())
|
||||
{
|
||||
@@ -363,7 +362,7 @@ public slots:
|
||||
return;
|
||||
}
|
||||
it.value() = std::make_shared<QPixmap>(resImgInput);
|
||||
QMutexLocker locker(&switchBoxMutex);
|
||||
QMutexLocker locker(&switchViewerMutex);
|
||||
if (type == switchBox.currentText())
|
||||
showImgOnGraphicsView(resImgInput);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include <qdialog.h>
|
||||
#include <global.h>
|
||||
#include <nlohmannJson.hpp>
|
||||
#include <qlayout.h>
|
||||
|
||||
class runCommandWidget : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit runCommandWidget(QWidget* parent = nullptr)
|
||||
: QDialog(parent) {
|
||||
this->setWindowTitle("执行命令");
|
||||
this->resize(400, 800);
|
||||
//setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint); // 去掉边框 //现在、、
|
||||
//setAttribute(Qt::WA_TranslucentBackground); // 背景透明
|
||||
this->setObjectName("JsonParamTableEditor");
|
||||
this->setStyleSheet(QString("QDialog#JsonParamTableEditor {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue));
|
||||
|
||||
btnWidgets = new QListWidget(this);
|
||||
btnWidgets->setStyleSheet("background: transparent;");
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(btnWidgets);
|
||||
this->setFixedSize(sizeX, sizeY);
|
||||
}
|
||||
|
||||
signals:
|
||||
void excuteCommandPreset(QString uuid);
|
||||
|
||||
public slots:
|
||||
void addBtn(const QString& btnName, const QString& tip, const QString& uuid) {
|
||||
QListWidgetItem* item = new QListWidgetItem(btnWidgets);
|
||||
item->setSizeHint(QSize(sizeX - 30, 30));
|
||||
btnWidgets->addItem(item);
|
||||
fancyButtonText* funcBtn = new fancyButtonText(sizeX - 30, 30, btnName, tip);
|
||||
btnWidgets->setItemWidget(item, funcBtn);
|
||||
connect(funcBtn, &fancyButtonText::clicked, this, [this, uuid]() {
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(
|
||||
this, // 父窗口
|
||||
"提示", // 标题
|
||||
"确定要执行此操作吗?", // 内容
|
||||
QMessageBox::Yes | QMessageBox::No // 按钮
|
||||
);
|
||||
if (reply == QMessageBox::Yes) {
|
||||
emit excuteCommandPreset(uuid);
|
||||
}
|
||||
});
|
||||
}
|
||||
private:
|
||||
int sizeX = 300, sizeY = 500;
|
||||
QListWidget* btnWidgets;
|
||||
};
|
||||
#pragma once
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <string>
|
||||
#include <global.h>
|
||||
#include <generalJsonParsing.hpp>
|
||||
#include <sql/qSqlBase.h>
|
||||
class appConfig
|
||||
{
|
||||
public:
|
||||
@@ -19,7 +20,7 @@ public:
|
||||
nlohmann::ordered_json settingJson;
|
||||
std::string softwareTile;//软件标题
|
||||
std::string imgSavePath;//原图存储路径
|
||||
|
||||
SQLiteDB* g_db = nullptr;
|
||||
//triggerStruct _triggerStruct;
|
||||
//std::vector< cameraStruct> _cameraStructs;
|
||||
//sqlConfigStruct _sqlConfigStruct;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <appConfig/appConfig.h>
|
||||
//QT
|
||||
#include <qtimer.h>
|
||||
#include <sql/qSqlBase.h>
|
||||
//
|
||||
#include "interface.h"
|
||||
#include <qtBridge.h>
|
||||
@@ -57,7 +56,7 @@ public:
|
||||
logService _logService;
|
||||
appConfig _appConfig;
|
||||
backEnd backend;
|
||||
SQLiteDB* g_db = nullptr;
|
||||
|
||||
appCore(){
|
||||
|
||||
};
|
||||
@@ -67,7 +66,7 @@ public slots:
|
||||
|
||||
}
|
||||
void recvInitFinished() {
|
||||
g_db = backend.backend->getDatabase();
|
||||
_appConfig.g_db = backend.backend->getDatabase();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ logService::logService()
|
||||
_logToQtWidget->sendStdLogSignal(outPutMsg);//Qt日志界面
|
||||
_logToQtWidget->sendMainWindowStdLogSignal(outPutMsg);//Qt主界面
|
||||
_logService->qtLogger->LogDebug("[STD]" + output);//spdLog
|
||||
});
|
||||
_stdConsoleRedirector->registerCallback([&](const std::string& output) {
|
||||
_stdConsoleRedirector->writeToConsole(output);
|
||||
});
|
||||
// QT日志到 spdLog Qt日志界面
|
||||
@@ -27,7 +29,9 @@ logService::logService()
|
||||
_logService->qtLogger->LogDebug("[QT]" + output.toStdString());
|
||||
_logToQtWidget->sendQtLogSignal(output);//Qt日志界面
|
||||
});
|
||||
|
||||
_qtRediretor->registerCallback([&](const QString& output) {
|
||||
_stdConsoleRedirector->writeToConsole(output.toStdString()); // 逐个字符写入缓冲区
|
||||
});
|
||||
|
||||
}
|
||||
logService::~logService()
|
||||
|
||||
@@ -38,6 +38,10 @@ public:
|
||||
logToQtWidget* _logToQtWidget;
|
||||
//SpdLogger stdLogger;
|
||||
SpdLogger* qtLogger;
|
||||
void disableConsole() {
|
||||
_stdConsoleRedirector->eraseSecondCallback();
|
||||
_qtRediretor->eraseSecondCallback();
|
||||
}
|
||||
logService();
|
||||
~logService();
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <qapplication.h>
|
||||
#include <qfileinfo.h>
|
||||
|
||||
#include <mutex>
|
||||
class qtRediretor
|
||||
{
|
||||
public:
|
||||
@@ -11,10 +11,16 @@ public:
|
||||
}
|
||||
void sendMsg(QString& msg)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
for (auto& callback : callbacks)
|
||||
callback(msg);
|
||||
}
|
||||
void eraseSecondCallback() {
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
callbacks.erase(callbacks.begin() + 1, callbacks.end());
|
||||
}
|
||||
private:
|
||||
std::mutex consoleLock;
|
||||
std::vector<CallbackType> callbacks;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ public:
|
||||
void registerCallback(CallbackType callback) {
|
||||
callbacks.push_back(callback);
|
||||
}
|
||||
void eraseSecondCallback() {
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
callbacks.erase(callbacks.begin() + 1, callbacks.end());
|
||||
}
|
||||
void writeToConsole(const std::string& str) {
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
originalBuffer->sputn(str.c_str(), str.size());
|
||||
|
||||
@@ -128,6 +128,14 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge*
|
||||
QObject::connect(bridge, &qtFuncBridge::histogramWidgetAddData,
|
||||
_MainWindow, [=](std::vector<std::string>defects)
|
||||
{_MainWindow->_displayWidget->_dayNightShiftHistogramWidget->addDefect(defects); });
|
||||
QObject::connect(bridge, &qtFuncBridge::setPlcConnectionError,
|
||||
_MainWindow, [=]() {_MainWindow->_displayWidget->_ConnectionWidget->setPlcDisconnected(); });
|
||||
QObject::connect(bridge, &qtFuncBridge::setPlcConnectionOk,
|
||||
_MainWindow, [=]() {_MainWindow->_displayWidget->_ConnectionWidget->setPlcConnected(); });
|
||||
QObject::connect(bridge, &qtFuncBridge::setCamConnectionError,
|
||||
_MainWindow, [=]() {_MainWindow->_displayWidget->_ConnectionWidget->setCamDisconnected(); });
|
||||
QObject::connect(bridge, &qtFuncBridge::setCamConnectionOk,
|
||||
_MainWindow, [=]() {_MainWindow->_displayWidget->_ConnectionWidget->setCamConnected(); });
|
||||
//登录界面
|
||||
QObject::connect(bridge, &qtFuncBridge::initResult,
|
||||
_MainWindow, &MainWindow::recvInitFinished);
|
||||
@@ -140,6 +148,13 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge*
|
||||
//波形图
|
||||
QObject::connect(bridge, &qtFuncBridge::summaryData_addData,
|
||||
_MainWindow, &MainWindow::slot_summaryData_addData);
|
||||
|
||||
//排障
|
||||
QObject::connect(bridge, &qtFuncBridge::runCommand_addBtn,
|
||||
_MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addBtn);
|
||||
QObject::connect(_MainWindow->_displayWidget->_runCommandWidget,
|
||||
&runCommandWidget::excuteCommandPreset,
|
||||
[=](QString uuid) {_core->backend.backend->excuteCliCommandPreset(uuid); });
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
@@ -194,6 +209,7 @@ int main(int argc, char* argv[])
|
||||
#if HIDE_CONSOLE
|
||||
if (hWnd) {
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
_core._logService.disableConsole();
|
||||
}// 隐藏控制台窗口
|
||||
#endif
|
||||
return a.exec();
|
||||
|
||||
@@ -40,8 +40,8 @@ FILE(GLOB UI_FILES "./*.ui")
|
||||
|
||||
|
||||
#find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED)
|
||||
|
||||
add_library(${CURRENT_FOLDER} SHARED
|
||||
${HEAD_FILES}
|
||||
@@ -64,6 +64,7 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Network
|
||||
Qt${QT_VERSION_MAJOR}::Sql
|
||||
)
|
||||
|
||||
|
||||
|
||||
+5
-1
@@ -2,4 +2,8 @@ json1.0.4
|
||||
心跳改为数组,循环发送
|
||||
去除Triggers{readNum,sleepTime,writeType}
|
||||
json1.0.5
|
||||
批量读取改为数组 readAllCmd
|
||||
批量读取改为数组 readAllCmd
|
||||
json1.0.6
|
||||
加入心跳间隔heartBeatIntervalMS
|
||||
加入图像压缩阈值uiShowImgCompressThreshold
|
||||
加入睡眠时间sleepIntervalMS
|
||||
Reference in New Issue
Block a user