V20251106-2.1.7
修复oneTriggerCaptrueTimes不生效的问题。 修复logwidget可能导致的死锁问题。 优化日志显示。 优化mission错误处理。 修改重试功能。 优化histogramWidget显示。
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#pragma execution_character_set("utf-8")
|
||||
const std::string softwareVersion = "20251104-2.1.6";
|
||||
const std::string softwareVersion = "20251106-2.1.7";
|
||||
const std::string euiJsonVersion = "1.0.6";
|
||||
#define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径
|
||||
#define saveImgEnable 1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <HalconCpp.h>
|
||||
#include <opencv.hpp>
|
||||
#include <ios>
|
||||
#include <algorithm>
|
||||
#include <handleAI.h>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
@@ -753,6 +754,62 @@ static cv::Mat tiledImages(std::vector<cv::Mat>& imgs)
|
||||
return showMat;
|
||||
};
|
||||
|
||||
/**
|
||||
* 快速去噪函数
|
||||
*
|
||||
* 说明:
|
||||
* - 优先使用均值滤波(box filter)实现快速平滑;
|
||||
* - 对明显的椒盐噪声可开启中值滤波(按通道处理,适用于8U/16U);
|
||||
* - 指定较大核或需要可控平滑强度时,使用高斯滤波作为兜底。
|
||||
*
|
||||
* 参数:
|
||||
* - inputMat 输入图像(支持单通道/多通道);
|
||||
* - outputMat 输出图像;
|
||||
* - kernelSize 卷积核大小,必须为奇数且>=3(传偶数会自动+1);
|
||||
* - sigma 高斯滤波标准差,<=0 表示走OpenCV自动推导;
|
||||
* - useMedian 是否启用中值滤波(更抗椒盐噪声,速度较均值略慢)。
|
||||
*/
|
||||
static void denoiseImage(const cv::Mat& inputMat, cv::Mat& outputMat, int kernelSize = 3, double sigma = 0.0, bool useMedian = false)
|
||||
{
|
||||
if (inputMat.empty()) {
|
||||
outputMat.release();
|
||||
return;
|
||||
}
|
||||
|
||||
int k = kernelSize;
|
||||
if (k < 3) k = 3; // 最小有效核大小
|
||||
|
||||
if ((k & 1) == 0) {
|
||||
++k; // 转换为奇数核
|
||||
}
|
||||
|
||||
// 快速路径(椒盐噪声):启用中值滤波;多通道按通道分别处理
|
||||
if (useMedian && (inputMat.depth() == CV_8U || inputMat.depth() == CV_16U)) {
|
||||
if (inputMat.channels() == 1) {
|
||||
cv::medianBlur(inputMat, outputMat, k);
|
||||
return;
|
||||
} else {
|
||||
std::vector<cv::Mat> ch;
|
||||
cv::split(inputMat, ch);
|
||||
for (auto& c : ch) {
|
||||
cv::medianBlur(c, c, k);
|
||||
}
|
||||
cv::merge(ch, outputMat);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认快速路径:小核且未指定sigma时使用均值滤波(分离实现,速度快)
|
||||
if (k <= 5 && sigma <= 0.0) {
|
||||
cv::blur(inputMat, outputMat, cv::Size(k, k), cv::Point(-1, -1), cv::BORDER_DEFAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
// 兜底:使用可分离高斯滤波,适合较大核或需要指定平滑强度的场景
|
||||
const double sigmaChecked = getMax(0.0, sigma);
|
||||
cv::GaussianBlur(inputMat, outputMat, cv::Size(k, k), sigmaChecked, sigmaChecked, cv::BORDER_DEFAULT);
|
||||
}
|
||||
|
||||
// 字符编码转换:GBK 编码的 std::string 转为 UTF-8 编码的 std::string(基于 Qt 5.14.x)
|
||||
// 入参:gbkStr - GBK/GB2312/GB18030 字节序列(std::string 仅作为原始字节容器)
|
||||
// 返回:UTF-8 编码的字节序列(std::string)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <devguid.h>
|
||||
#include <shellapi.h>
|
||||
#include <ShlObj.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <QPixmap>
|
||||
#include <QFileIconProvider>
|
||||
#include <QFileInfo>
|
||||
@@ -258,4 +260,82 @@ static QIcon getFileIcon(const QString& filePath, const QSize& size) {
|
||||
QPixmap pixmap = icon.pixmap(size);
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
|
||||
static bool restartProgram(bool asAdmin = false, bool exitCurrent = true, int delayMs = 0) {
|
||||
wchar_t exePath[MAX_PATH];
|
||||
if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
std::wstring params;
|
||||
if (argv && argc > 1) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
const wchar_t* arg = argv[i];
|
||||
bool needQuote = wcspbrk(arg, L" \t\"'") != nullptr;
|
||||
if (i > 1) params.push_back(L' ');
|
||||
if (needQuote) {
|
||||
params.push_back(L'"');
|
||||
for (const wchar_t* p = arg; *p; ++p) {
|
||||
if (*p == L'"') params.push_back(L'\\'), params.push_back(L'"');
|
||||
else params.push_back(*p);
|
||||
}
|
||||
params.push_back(L'"');
|
||||
} else {
|
||||
params.append(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argv) LocalFree(argv);
|
||||
|
||||
if (delayMs <= 0) {
|
||||
SHELLEXECUTEINFOW sei{};
|
||||
sei.cbSize = sizeof(sei);
|
||||
sei.lpVerb = asAdmin ? L"runas" : L"open";
|
||||
sei.lpFile = exePath;
|
||||
sei.lpParameters = params.empty() ? nullptr : params.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
if (!ShellExecuteExW(&sei)) return false;
|
||||
if (exitCurrent) ExitProcess(0);
|
||||
return true;
|
||||
} else {
|
||||
std::wstring exeEsc;
|
||||
for (const wchar_t* p = exePath; *p; ++p) {
|
||||
if (*p == L'\'') exeEsc.push_back(L'\''); // duplicate single quote for PS literal
|
||||
exeEsc.push_back(*p);
|
||||
}
|
||||
std::wstring argsEsc;
|
||||
if (!params.empty()) {
|
||||
for (const wchar_t* p = params.c_str(); *p; ++p) {
|
||||
if (*p == L'\'') argsEsc.push_back(L'\'');
|
||||
argsEsc.push_back(*p);
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring psParam = L"-NoProfile -WindowStyle Hidden -Command \"Wait-Process -Id ";
|
||||
psParam += std::to_wstring(GetCurrentProcessId());
|
||||
psParam += L"; Start-Sleep -Milliseconds ";
|
||||
psParam += std::to_wstring(delayMs);
|
||||
psParam += L"; Start-Process -FilePath '";
|
||||
psParam += exeEsc;
|
||||
psParam += L"'";
|
||||
if (!argsEsc.empty()) {
|
||||
psParam += L" -ArgumentList '";
|
||||
psParam += argsEsc;
|
||||
psParam += L"'";
|
||||
}
|
||||
psParam += L"\"";
|
||||
|
||||
SHELLEXECUTEINFOW sei{};
|
||||
sei.cbSize = sizeof(sei);
|
||||
sei.lpVerb = asAdmin ? L"runas" : L"open";
|
||||
sei.lpFile = L"powershell.exe";
|
||||
sei.lpParameters = psParam.c_str();
|
||||
sei.nShow = SW_HIDE;
|
||||
if (!ShellExecuteExW(&sei)) return false;
|
||||
if (exitCurrent) ExitProcess(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#pragma once
|
||||
+6
-3
@@ -88,6 +88,7 @@ public:
|
||||
std::string cameraName;
|
||||
QString viewerName;
|
||||
std::vector<sx_581_address>address;
|
||||
int oneTriggerCaptrueTimes = 1;
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
@@ -101,7 +102,7 @@ public:
|
||||
/// <param name="bridgeIn">默认</param>
|
||||
/// <param name="_processAlgoCallback">算法函数</param>
|
||||
/// <param name="resultHandlerIn"></param>
|
||||
void init(std::string cameraNameIn, QString viewerNameIN, std::vector<sx_581_address> addressIN, int oneTriggerCaptrueTimes,
|
||||
void init(std::string cameraNameIn, QString viewerNameIN, std::vector<sx_581_address> addressIN, int oneTriggerCaptrueTimesIN,
|
||||
paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn,
|
||||
typename detCallbackChain<paramTemplte, sx_581_address>::processAlgoCallback _processAlgoCallback,
|
||||
QString saveObjectNameIN = "") {
|
||||
@@ -112,6 +113,7 @@ public:
|
||||
bridge = bridgeIn;
|
||||
address = addressIN;
|
||||
saveObjectName = saveObjectNameIN;
|
||||
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
|
||||
generalDet = new detCallbackChain<paramTemplte, sx_581_address>(_serviceManager, _detParams, bridge);
|
||||
generalDet->registerProcessAlgoCallback(_processAlgoCallback);
|
||||
//单次触发器条件
|
||||
@@ -145,10 +147,11 @@ public:
|
||||
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);//获取相机
|
||||
camera->clearCache();//清除缓存
|
||||
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(
|
||||
QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包
|
||||
QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包
|
||||
QString saveObjectName = "";
|
||||
data->saveObjectName = saveObjectName;
|
||||
camera->captureImage(data);//拍照
|
||||
for (int i = 0; i < oneTriggerCaptrueTimes; i++)
|
||||
camera->captureImage(data);//拍照
|
||||
generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号
|
||||
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
|
||||
}
|
||||
|
||||
+16
-6
@@ -107,6 +107,7 @@ public:
|
||||
std::string cameraName;
|
||||
QString viewerName;
|
||||
std::map<int, yh_581_address>address;
|
||||
int oneTriggerCaptrueTimes = 1;
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
@@ -120,7 +121,7 @@ public:
|
||||
/// <param name="bridgeIn">默认</param>
|
||||
/// <param name="_processAlgoCallback">算法函数</param>
|
||||
/// <param name="resultHandlerIn"></param>
|
||||
void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount,int oneTriggerCaptrueTimes,
|
||||
void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount,int oneTriggerCaptrueTimesIN,
|
||||
paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn,
|
||||
typename detCallbackChain<paramTemplte, yh_581_address>::processAlgoCallback _processAlgoCallback,
|
||||
QString saveObjectNameIN = "") {
|
||||
@@ -129,6 +130,7 @@ public:
|
||||
_serviceManager = _serviceManagerIn;
|
||||
_detParams = detParamsIn;
|
||||
bridge = bridgeIn;
|
||||
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
|
||||
|
||||
saveObjectName = saveObjectNameIN;
|
||||
generalDet = new detCallbackChain<paramTemplte, yh_581_address>(_serviceManager, _detParams, bridge);
|
||||
@@ -170,9 +172,12 @@ public:
|
||||
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);
|
||||
camera->clearCache();
|
||||
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(
|
||||
QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包
|
||||
QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包
|
||||
data->saveObjectName = saveObjectName;
|
||||
camera->captureImage(data);//拍照
|
||||
|
||||
for(int i=0;i< oneTriggerCaptrueTimes;i++)
|
||||
camera->captureImage(data);//拍照
|
||||
|
||||
generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法
|
||||
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
|
||||
}
|
||||
@@ -199,6 +204,7 @@ public:
|
||||
std::string cameraName;
|
||||
QString viewerName;
|
||||
std::map<int, yh_581_address>address;
|
||||
int oneTriggerCaptrueTimes = 1;
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
@@ -212,7 +218,7 @@ public:
|
||||
/// <param name="bridgeIn">默认</param>
|
||||
/// <param name="_processAlgoCallback">算法函数</param>
|
||||
/// <param name="resultHandlerIn"></param>
|
||||
void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount, int oneTriggerCaptrueTimes,
|
||||
void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount, int oneTriggerCaptrueTimesIN,
|
||||
paramTemplte2* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn,
|
||||
typename detCallbackChain<paramTemplte2, yh_581_address>::processAlgoCallback _processAlgoCallback,
|
||||
QString saveObjectNameIN = "") {
|
||||
@@ -221,6 +227,7 @@ public:
|
||||
_serviceManager = _serviceManagerIn;
|
||||
_detParams = detParamsIn;
|
||||
bridge = bridgeIn;
|
||||
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
|
||||
|
||||
saveObjectName = saveObjectNameIN;
|
||||
generalDet = new detCallbackChain<paramTemplte2, yh_581_address>(_serviceManager, _detParams, bridge);
|
||||
@@ -253,9 +260,12 @@ public:
|
||||
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);
|
||||
camera->clearCache();
|
||||
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(
|
||||
QString::fromStdString(cameraName), sn, 1, camera->config.oriSaveFormat);//创建数据包
|
||||
QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包
|
||||
data->saveObjectName = saveObjectName;
|
||||
camera->captureImage(data);//拍照
|
||||
|
||||
for (int i = 0; i < oneTriggerCaptrueTimes; i++)
|
||||
camera->captureImage(data);//拍照
|
||||
|
||||
generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法
|
||||
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void Backend::init(SQLiteDB* db, qtFuncBridge* bridgeIn, nlohmann::ordered_json&
|
||||
_serviceManager._csvWriter = _csvWriter;
|
||||
_serviceManager._paramSyncManager = _paramSyncManager;
|
||||
//CLI 只在首次初始化创建
|
||||
connect(bridge, &qtFuncBridge::restartInit, this, &Backend::restartInit);
|
||||
//connect(bridge, &qtFuncBridge::restartInit, this, &Backend::restartInit);
|
||||
_cliManager = new CLIManager(&_serviceManager, bridge);
|
||||
initOnce = true;
|
||||
}
|
||||
@@ -58,6 +58,8 @@ void Backend::run() {
|
||||
bool res = _missionLoader.loadMission(missionJson["missionDllPath"]);
|
||||
if (res == false) {
|
||||
emit bridge->loadingWindow_appendInitLog("初始化Mission失败!请检查路径是否正确.", "red");
|
||||
emit bridge->initResult(InitFailure);
|
||||
return;
|
||||
}
|
||||
_missionLoader.getmission(missionJson["missionDllPath"])->initBasic(
|
||||
&_serviceManager,
|
||||
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
}
|
||||
private:
|
||||
QString defaultPath = "{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{HH}H/{processResult}/{SN}/";
|
||||
QString defaultFileName = "{SN}_{cameraName}_{index}";
|
||||
QString defaultFileName = "{SN}_{cameraName}_{index}_{HH-mm-ss}";
|
||||
};
|
||||
struct saveJob {
|
||||
saveJob(std::string jobNameIn) :jobName(jobNameIn) {}
|
||||
|
||||
@@ -5,6 +5,8 @@ class MissionLoader {
|
||||
MissionLoader() = default;
|
||||
~MissionLoader() = default;
|
||||
bool loadMission(const std::string& missionPath) {
|
||||
if (QFile(QString::fromStdString("./" + missionPath + ".dll")).exists() == false)
|
||||
return false;
|
||||
hDlls[missionPath] = LoadLibrary(missionPath.c_str());
|
||||
if (!hDlls[missionPath]) {
|
||||
std::cerr << "Failed to load Misson DLL!" << std::endl;
|
||||
|
||||
@@ -215,11 +215,6 @@ public:
|
||||
|
||||
appendColoredMessagesBatch(state.textWidget, logCache[index]);
|
||||
logCache[index].clear();
|
||||
|
||||
// 自动滚动到底部
|
||||
if (state.autoScroll) {
|
||||
scrollToBottom(state.textWidget);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -191,164 +191,14 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
//class histogramWidget : public QWidget {
|
||||
// Q_OBJECT
|
||||
//public:
|
||||
// histogramWidget(QString title, QWidget* parent = nullptr)
|
||||
// : QWidget(parent), enableAnimation(true)
|
||||
// {
|
||||
// setStyleSheet("background-color: rgb(50, 55, 60); color: white;");
|
||||
// initUI(title);
|
||||
// initChart();
|
||||
// }
|
||||
//
|
||||
// void setTitle(const QString& text) {
|
||||
// titleLabel->setText(text);
|
||||
// }
|
||||
//
|
||||
// void setStats(int total, int bad, int good, double goodRate) {
|
||||
// labelLeft->setText(QString(u8"检测总数: %1\n不良数: %2").arg(total).arg(bad));
|
||||
// labelRight->setText(QString(u8"良品数: %1\n良品率: %2%").arg(good).arg(goodRate, 0, 'f', 2));
|
||||
// }
|
||||
//
|
||||
// void addBarCategory(const QString& category, double value) {
|
||||
// categories << category;
|
||||
// *barSet << value;
|
||||
// updateChart();
|
||||
// }
|
||||
//
|
||||
// void clearBarData() {
|
||||
// categories.clear();
|
||||
// barSet->remove(0, barSet->count());
|
||||
// updateChart();
|
||||
// }
|
||||
//
|
||||
// void setAnimationEnabled(bool enabled) {
|
||||
// enableAnimation = enabled;
|
||||
// chart->setAnimationOptions(enableAnimation ? QChart::SeriesAnimations : QChart::NoAnimation);
|
||||
// }
|
||||
//
|
||||
//private:
|
||||
// QLabel* titleLabel;
|
||||
// QLabel* labelLeft;
|
||||
// QLabel* labelRight;
|
||||
// QChart* chart;
|
||||
// QChartView* chartView;
|
||||
// QBarSet* barSet;
|
||||
// QStringList categories;
|
||||
// bool enableAnimation;
|
||||
//
|
||||
// void initUI(QString title) {
|
||||
// QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
||||
//
|
||||
// titleLabel = new QLabel(title);
|
||||
// titleLabel->setStyleSheet("font-size: 16px; font-weight: bold;");
|
||||
// mainLayout->addWidget(titleLabel);
|
||||
//
|
||||
// QHBoxLayout* dataLayout = new QHBoxLayout();
|
||||
// labelLeft = new QLabel(u8"检测总数\n不良数");
|
||||
// labelRight = new QLabel(u8"良品数\n良品率");
|
||||
// labelLeft->setAlignment(Qt::AlignLeft);
|
||||
// labelRight->setAlignment(Qt::AlignLeft);
|
||||
// dataLayout->addWidget(labelLeft);
|
||||
// dataLayout->addStretch();
|
||||
// dataLayout->addWidget(labelRight);
|
||||
// mainLayout->addLayout(dataLayout);
|
||||
//
|
||||
// chartView = new QChartView();
|
||||
// chartView->setRenderHint(QPainter::Antialiasing);
|
||||
// mainLayout->addWidget(chartView);
|
||||
//
|
||||
// this->setStyleSheet(
|
||||
// "QLineEdit { background-color: rgb(50, 55, 60); color: white; border-radius: 4px; padding: 2px; } "
|
||||
// "QLabel { color: white; } "
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// void initChart() {
|
||||
// barSet = new QBarSet("数量");
|
||||
// *barSet << 0; // 初始一个数据
|
||||
//
|
||||
// QBarSeries* series = new QBarSeries();
|
||||
// series->append(barSet);
|
||||
//
|
||||
// chart = new QChart();
|
||||
// chart->addSeries(series);
|
||||
// chart->setBackgroundVisible(false);
|
||||
// chart->legend()->hide();
|
||||
// chart->setAnimationOptions(enableAnimation ? QChart::SeriesAnimations : QChart::NoAnimation);
|
||||
//
|
||||
// QBarCategoryAxis* axisX = new QBarCategoryAxis();
|
||||
// axisX->append(categories);
|
||||
// chart->addAxis(axisX, Qt::AlignBottom);
|
||||
// series->attachAxis(axisX);
|
||||
//
|
||||
// QValueAxis* axisY = new QValueAxis();
|
||||
// axisY->setLabelFormat("%.0f");
|
||||
// axisY->setLabelsBrush(QBrush(QColor(255, 255, 255)));
|
||||
// axisY->setRange(0, 100); // 初始范围,后面会动态调整
|
||||
// chart->addAxis(axisY, Qt::AlignLeft);
|
||||
// series->attachAxis(axisY);
|
||||
//
|
||||
// chartView->setChart(chart);
|
||||
//
|
||||
// chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
// chartView->setContentsMargins(0, 0, 0, 0);
|
||||
// chartView->setStyleSheet("background-color: rgb(50, 55, 60); border: none;");
|
||||
// chart->setMargins(QMargins(0, 0, 0, 0)); // 去掉 QChart 的四周空白
|
||||
// chart->setBackgroundBrush(QBrush(QColor(50, 55, 60)));
|
||||
// }
|
||||
//
|
||||
// void updateChart() {
|
||||
// QMutexLocker locker(&mutex);
|
||||
// chart->removeAllSeries();
|
||||
//
|
||||
// QBarSeries* series = new QBarSeries();
|
||||
// series->append(barSet);
|
||||
// chart->addSeries(series);
|
||||
//
|
||||
// QBarCategoryAxis* axisX = new QBarCategoryAxis();
|
||||
// axisX->append(categories);
|
||||
// chart->addAxis(axisX, Qt::AlignBottom);
|
||||
// series->attachAxis(axisX);
|
||||
//
|
||||
// QValueAxis* axisY = new QValueAxis();
|
||||
// axisY->setLabelFormat("%.0f");
|
||||
// // 添加每个柱子上方的数值标签
|
||||
// for (int i = 0; i < barSet->count(); ++i) {
|
||||
// QGraphicsSimpleTextItem* label = new QGraphicsSimpleTextItem(QString::number((*barSet)[i]));
|
||||
// label->setBrush(QBrush(Qt::white));
|
||||
// QPointF pos = chart->mapToPosition(QPointF(i, (*barSet)[i]), series);
|
||||
// label->setPos(pos.x() - 5, pos.y() - 20);
|
||||
// chart->scene()->addItem(label);
|
||||
// }
|
||||
//
|
||||
// chart->setAnimationOptions(enableAnimation ? QChart::SeriesAnimations : QChart::NoAnimation);
|
||||
// }
|
||||
//
|
||||
//protected:
|
||||
// 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);
|
||||
// }
|
||||
//private:
|
||||
// QMutex mutex;
|
||||
//};
|
||||
|
||||
class dayNightShiftHistogramWidget : public QWidget {
|
||||
public:
|
||||
histogramWidget* dayHistogramWidget;
|
||||
histogramWidget* nightHistogramWidget;
|
||||
dayNightShiftHistogramWidget() {
|
||||
dayHistogramWidget = new histogramWidget("白班(08:30-20:30)");
|
||||
nightHistogramWidget = new histogramWidget("夜班(20:30-08:30)");
|
||||
QString ymd = QDate::currentDate().toString("yyyy-MM-dd");
|
||||
dayHistogramWidget = new histogramWidget(ymd + "白班(08:30-20:30)");
|
||||
nightHistogramWidget = new histogramWidget(ymd +"夜班(20:30-08:30)");
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -366,15 +216,18 @@ public:
|
||||
//}
|
||||
void addDefect(std::vector<std::string>defects) {
|
||||
bool isDay = isDayShiftNow();
|
||||
//判断是否切换班次,如切换则清空下个班次的数据
|
||||
//判断是否切换班次,如切换则清空当前班次的数据
|
||||
if (lastIsDayState != isDay) {
|
||||
QString ymd = QDate::currentDate().toString("yyyy-MM-dd");
|
||||
if (isDay == true) {
|
||||
nightHistogramWidget->clearBarData();
|
||||
nightDefectMap.clear();
|
||||
}
|
||||
else {
|
||||
dayHistogramWidget->clearBarData();
|
||||
dayDefectMap.clear();
|
||||
dayHistogramWidget->setTitle(ymd + "白班(08:30-20:30)");
|
||||
}
|
||||
else {
|
||||
nightHistogramWidget->clearBarData();
|
||||
nightDefectMap.clear();
|
||||
nightHistogramWidget->setTitle(ymd + "夜班(20:30-08:30)");
|
||||
}
|
||||
okCnt = 0;
|
||||
ngCnt = 0;
|
||||
|
||||
@@ -13,14 +13,13 @@ private:
|
||||
// 禁用拷贝构造函数和赋值运算符
|
||||
appConfig(const appConfig&) = delete;
|
||||
appConfig& operator=(const appConfig&) = delete;
|
||||
|
||||
public:
|
||||
// 获取单例实例
|
||||
static appConfig& getInstance() {
|
||||
static appConfig instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool exitWithRestart = false;
|
||||
void parsingSettingJson();
|
||||
void loadSetting() {
|
||||
parsingSettingJson();
|
||||
|
||||
@@ -9,10 +9,29 @@ static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context,
|
||||
if (!qtRediretor_Ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString typeText = "";
|
||||
switch (type)
|
||||
{
|
||||
case QtDebugMsg:
|
||||
typeText = "DEBUG";
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
typeText = "WARNING";
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
typeText = "ERROR";
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
typeText = "ERROR";
|
||||
break;
|
||||
default:
|
||||
typeText = "INFO";
|
||||
break;
|
||||
}
|
||||
// 构建格式化的日志消息
|
||||
// 格式: [文件名:行号] 消息内容
|
||||
QString outputMessage = QString("[%1:%2] %3")
|
||||
QString outputMessage = QString("[%1][%2:%3] %4")
|
||||
.arg(typeText)
|
||||
.arg(QFileInfo(context.file).fileName())
|
||||
.arg(context.line)
|
||||
.arg(msg);
|
||||
|
||||
+13
-1
@@ -186,6 +186,11 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge*
|
||||
config.missionJson["backend"] = _core->_backEnd.backend->getJson();
|
||||
config.saveSettingJson();
|
||||
}, Qt::DirectConnection);
|
||||
|
||||
QObject::connect(bridge, &qtFuncBridge::restartInit,[=]() {
|
||||
appConfig::getInstance().exitWithRestart = true;
|
||||
QApplication::quit();
|
||||
});
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
@@ -249,5 +254,12 @@ int main(int argc, char* argv[])
|
||||
if (config.dataBase) delete config.dataBase;
|
||||
config.dataBase = nullptr;
|
||||
});
|
||||
return a.exec();
|
||||
|
||||
int qtRes = a.exec();
|
||||
if (config.exitWithRestart) {
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
std::cout << "程序将在五秒后重启..." << std::endl;
|
||||
restartProgram(false,true,5000);
|
||||
}
|
||||
return qtRes;
|
||||
}
|
||||
@@ -166,6 +166,7 @@ static bool ManHan(std::shared_ptr <detData> data, mfd_detParams* _detParams, yh
|
||||
}
|
||||
static bool YuHan(std::shared_ptr <detData> data, mfd_detParams* _detParams, yh_581_address address){
|
||||
try {
|
||||
data->service->_missionResultHandle->toBarChart("", true, {"测试"});
|
||||
std::map<QString, QVariant> sqlMapData;
|
||||
sqlMapData["项目"] = "预焊";
|
||||
sqlMapData["相机"] = "相机" + address.triggerAddr;
|
||||
|
||||
Reference in New Issue
Block a user