#include "Logic_transfer.h" #include "qmutex.h" #include "qfuture.h" #include "QtConcurrent/qtconcurrent" #include "qmessagebox.h" QMutex log_mutex; void LogMsgOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg) { Q_UNUSED(context); QMutexLocker locker(&log_mutex); QByteArray localMsg = msg.toLocal8Bit(); QString log; QString log_info; QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); QString m_msg; QString m_name; QStringList msg_list; switch (type) { case QtDebugMsg: log.append(QString("[%1] [info] %2").arg(nowTime).arg(msg)); break; case QtInfoMsg: m_msg = msg; msg_list = m_msg.split("/"); if (msg_list.size() >= 2) { m_name = msg_list.at(1); m_msg.remove(0, m_name.size() + 2); } else { m_name = "null"; } log_info.append(QString("[%1] [info] %2").arg(nowTime).arg(m_msg)); break; case QtWarningMsg: log.append(QString("[%1] [warning] %2").arg(nowTime).arg(msg)); break; case QtCriticalMsg: log.append(QString("[%1] [critical] %2").arg(nowTime).arg(msg)); break; case QtFatalMsg: log.append(QString("[%1] [fatal] %2").arg(nowTime).arg(msg)); abort(); } QFile savefile; QString logTime = QDateTime::currentDateTime().toString("yyyy-MM-dd"); if (log != nullptr) { QDir m_dir = QApplication::applicationDirPath(); QString m_path = m_dir.path(); QDir m_checkdir = m_path + "/log/"; if (!m_checkdir.exists()) { m_checkdir.mkdir(m_checkdir.path()); } m_path = m_path + "/log/" + QString("%1_HanddleAI.log").arg(logTime); // m_path = m_path + "/log/" + QString("HanddleAI.log"); savefile.setFileName(m_path); if (!savefile.open(QIODevice::ReadWrite | QIODevice::Append)) { QString erinfo = savefile.errorString(); std::cout << " erinfo: " << erinfo.toStdString() << std::endl; return; } QTextStream out(&savefile); out << "\r" << log; savefile.close(); } if (log_info != nullptr) { QDir m_dir = QApplication::applicationDirPath(); QString m_path = m_dir.path(); QDir m_checkdir = m_path + "/log/"; if (!m_checkdir.exists()) { m_checkdir.mkdir(m_checkdir.path()); } m_path = m_path + "/log/" + QString("%1_%2.log").arg(logTime).arg(m_name); // m_path = m_path + "/log/" + QString("HanddleAI.log"); savefile.setFileName(m_path); if (!savefile.open(QIODevice::ReadWrite | QIODevice::Append)) { QString erinfo = savefile.errorString(); std::cout << " erinfo: " << erinfo.toStdString() << std::endl; return; } QTextStream out(&savefile); out << "\r" << log_info; savefile.close(); } int k = 0; // log_info.append(log); } QJsonObject Logic_transfer::load_camera_cfg(QString cfg) { QDir dir = QApplication::applicationDirPath(); currPath = dir.path(); json_cfg_file_path = currPath + "/config/" + cfg;//camera_cfg.json"; QJsonObject json_object; try { QJsonParseError jsonError; if (json_cfg_file_path.isEmpty()) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " JsonPath is null!"; return json_object; } QFile JsonFile; JsonFile.setFileName(json_cfg_file_path); if (!JsonFile.isReadable()) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_cfg.json not isReadable!"; //return json_object; } JsonFile.open(QIODevice::ReadOnly); QByteArray m_Byte = JsonFile.readAll(); if (m_Byte.isEmpty()) { qDebug() << __FUNCTION__ << " line:" << __LINE__ << json_cfg_file_path + " Content is empty"; JsonFile.close(); return json_object; } QJsonDocument jsonDocument(QJsonDocument::fromJson(m_Byte, &jsonError)); if (!jsonDocument.isNull() && jsonError.error == QJsonParseError::NoError) { if (jsonDocument.isObject()) { json_object = jsonDocument.object(); JsonFile.close(); return json_object; } } else { qCritical() << __FUNCTION__ << " line:" << __LINE__ << json_cfg_file_path + " is error!"; } JsonFile.close(); } catch (QString ev) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ev:" << ev; } return json_object; } bool ifRuntransfer = false; Logic_transfer::Logic_transfer() { showMutex = new QMutex; ifRuntransfer = true; //通用逻辑接口 //加载逻辑dll QLibrary* m_lib = new QLibrary("Hd_LogicDll_module.dll"); bool flag = m_lib->load(); if (!m_lib->isLoaded()) { qDebug() << __FUNCTION__ << __LINE__ << " Loaded error:" << m_lib->errorString(); delete m_lib; m_lib = nullptr; //return false; } else { CreateFunction createFun = (CreateFunction)m_lib->resolve("create"); ReleaseFunction releaseFun = (ReleaseFunction)m_lib->resolve("destory"); if (createFun && releaseFun) { Logic_ptr = nullptr; Logic_ptr = createFun(); destory_Logic = releaseFun; //加载并检查配置文件:bin/camera_cfg.json //m_jsonObj =load_camera_cfg(); //check_cmeraCfg(); //Logic_ptr->setJsonObject(m_jsonObj); //信号与槽 if(Logic_ptr) { //connect(Logic_ptr, SIGNAL(Logic_sendImage(QString, cv::Mat)), this, SLOT(base_Logic_sendImage(QString, cv::Mat))); // 传递图片 connect(Logic_ptr, SIGNAL(Logic_writeData(QString, QString, QString, QByteArray)), this, SLOT(base_Logic_writeData(QString, QString, QString, QByteArray)));// 传递数据 QFuturemuf = QtConcurrent::run(this, &Logic_transfer::check_sendImgStruct); connect(Logic_ptr, SIGNAL(Logic_sendTcpStatus(bool)), this, SLOT(base_Logic_sendTcpStatus(bool)));// 通信状态 connect(Logic_ptr, SIGNAL(Logic_cameraDisconnect(QString, bool)), this, SLOT(base_Logic_cameraDisconnect(QString,bool)));// x相机状态 } } } Sleep(50); } void Logic_transfer::check_sendImgStruct() { while (ifRuntransfer) { QQueue< sendImgStruct> myS; //if (Logic_ptr->queue_sendImgStruct.size() > 0) if (Logic_ptr->get_sendImgStruct(myS)) { //QMutexLocker locker(sendImgStructMutex); // 加锁 //sendImgStruct mS; //mS.send_Mat = myL.send_Mat; //mS.cameraKey_index = myL.cameraKey_index; ////堆积了,只显示最新的 //for (int i = 0; i < queue_sendImgStruct.size(); i++) // if (myL.cameraKey_index == queue_sendImgStruct[i].cameraKey_index) // { // queue_sendImgStruct.removeAt(i); // break; // } //queue_sendImgStruct.enqueue(mS); for (int i = 0; i < myS.size(); i++) { decodeImage(myS[i].cameraKey_index, myS[i].send_Mat); } myS.clear(); //Sleep(1); } Sleep(10); } } bool Logic_transfer::getShowQImage(QQueue< showImgStruct>& my_showImgStruct) { QMutexLocker locker(showMutex); // 加锁 //showImgStruct mS; if (queue_showImgStruct.size() > 0) { my_showImgStruct.append(queue_showImgStruct);// .dequeue(); queue_showImgStruct.clear(); return true; } return false; } void Logic_transfer::decodeImage(QString key, cv::Mat mtx) { try { if (!mtx.empty()) { //if ((mtx.dataend - mtx.datastart) != mtx.cols * mtx.rows * mtx.channels()) //尝试能否解决mtx内容异常问题 //{ // qCritical() << __FUNCTION__ << " line:" << __LINE__ << " mtx.dataend - mtx.datastart err!!:"; // return;// false; //} cv::Mat rgb; //while (mtx.cols > 2000 && mtx.rows > 2000) // cv::resize(mtx, mtx, cv::Size(), 0.1, 0.1); //吃cpu性能,i7 8700,4800*4800的resize耗时100ms;QImage*的scaled缩放,耗时200ms QImage* itemImage = nullptr; if (mtx.type() == CV_8UC1) { rgb = mtx.clone(); //mtx.data检查后,只有2个数据,clone崩溃 itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_Grayscale8); QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_Grayscale8); *itemImage = qim.copy(); } else if (mtx.type() == CV_16U) // 双通道转单通道显示 { cv::normalize(mtx, mtx, 0, 255, cv::NORM_MINMAX); cv::convertScaleAbs(mtx, rgb); itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_Grayscale8); QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_Grayscale8); *itemImage = qim.copy(); } else if (mtx.type() == CV_8UC3) { cv::cvtColor(mtx, rgb, cv::COLOR_BGR2RGB); itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_RGB888); QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB888); *itemImage = qim.copy(); } else if (mtx.type() == CV_8UC4) { cv::cvtColor(mtx, rgb, cv::COLOR_BGRA2RGBA); itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_ARGB32); QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_ARGB32); *itemImage = qim.copy(); } //emit LogicTransfer_sendImage(key, itemImage); QMutexLocker locker(showMutex); // 加锁 showImgStruct mS; mS.show_QImage = itemImage; mS.cameraKey_index = key; ////堆积了,只显示最新的 //for (int i = 0; i < queue_showImgStruct.size(); i++) // if (key == queue_showImgStruct[i].cameraKey_index) // { // queue_showImgStruct.removeAt(i); // break; // } queue_showImgStruct.enqueue(mS); } } catch (QString ev) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ev:" << ev; return;// false; } return;// true; } Logic_transfer::~Logic_transfer() { ifRuntransfer = false; Sleep(100); //通用逻辑接口 destory_Logic(Logic_ptr); } void Logic_transfer::base_Logic_sendTcpStatus(bool flag) { //emit LogicTransfer_sendTcpStatus(flag); if (flag) emit LogicTransfer_writeData("sendTcpStatus_true", "TCP", "TCP", "TCP"); else emit LogicTransfer_writeData("sendTcpStatus_false", "TCP", "TCP", "TCP"); } void Logic_transfer::base_Logic_writeData(QString key, QString cameraName, QString snInfo, QByteArray byte) { emit LogicTransfer_writeData(key, cameraName, snInfo, byte); } void Logic_transfer::base_Logic_cameraDisconnect(QString msg, bool status) { //emit LogicTransfer_cameraDisconnect(msg, status); if (status) emit LogicTransfer_writeData("cameraDisconnect_true", msg, "TCP", "TCP"); else emit LogicTransfer_writeData("cameraDisconnect_false", msg, "TCP", "TCP"); } //void Logic_transfer::base_Logic_CommunicationDisconnect(QString msg, bool status) //{ // emit LogicTransfer_CommunicationDisconnect(msg, status); //} //2、检查配置文件,返回检查结果(true表示配置文件正常,false表示异常)及字符串 //配置文件正常也有字符串返回,可按照返回结果进行弹窗提示。 bool Logic_transfer::checkJsonObject(QJsonObject obj, QString& errMessage) { if (Logic_ptr) return Logic_ptr->checkJsonObject(obj, errMessage); else return false; } //3、传递配置文件到通用逻辑框架 bool Logic_transfer::setJsonObject(QJsonObject obj) { QString saveLog = obj.value("是否写入日志").toString(); if (saveLog == "true") { //自动写Log日志功能;bin/Log qInstallMessageHandler(LogMsgOutput); } if (Logic_ptr) return Logic_ptr->setJsonObject(obj); else return false; return true; } //4、初始化任务 bool Logic_transfer::initTask() { if (Logic_ptr) return Logic_ptr->initTask(); else return false; return true; } //5、开始任务 bool Logic_transfer::startTask() { if (Logic_ptr) return Logic_ptr->startTask(); else return false; return true; } //6、停止任务、清理数据 bool Logic_transfer::stopTask() { if (Logic_ptr) return Logic_ptr->stopTask(); else return false; return true; } //7、退出所有类、释放模块 bool Logic_transfer::exitTask() { if (Logic_ptr) { Logic_ptr->disconnect(); return Logic_ptr->exitTask(); } else return false; return true; } //8、重新运行 bool Logic_transfer::restartTask() { if (Logic_ptr) return Logic_ptr->restartTask(); else return false; return true; } //发送指令给PLC bool Logic_transfer::sendPLC(QString cmd) { if (Logic_ptr) return Logic_ptr->sendPLC(cmd); else return false; return true; } //重新加载配置文件json,设置参数 bool Logic_transfer::reLoadJsonSetParameter(QStringList moduleKeyList) { if (Logic_ptr) return Logic_ptr->reLoadJsonSetParameter(moduleKeyList); else return false; return true; }