#include "FrameConfig.h" #include /**< std::pair std::make_pair */ #include #include FrameConfig::FrameConfig(QWidget* parent) : QWidget(parent) , m_pSingleton(nullptr) , m_strExePath("") , m_strDataPath("") , m_strModelType("") , m_pStatusInfoModel(nullptr) , strFileDir(".\\") , m_pValidProcess(nullptr) , m_pNetDataRecv(nullptr) , m_uiDataProcFinished(0) , m_uiDataProcNum(0) , m_bOfflineParse(false) // 是否正在进行离线解析 , m_bRealParse(false) // 是否正在进行实时解析 , m_uiParseStatus(0) { ui.setupUi(this); m_pSingleton = Singleton::CreateInstance(); m_mapUIntAfterProc.clear(); m_mapUIntProcess.clear(); initNetworkType(); // 初始化网络选择 loadConfigFiles(); // 加载XML配置文件 initStatusInfo(); // 初始化状态信息 connect(ui.pb_loadFile, &QPushButton::clicked, this, &FrameConfig::loadConfigFiles); connect(ui.pb_offlineParse, &QPushButton::clicked, this, &FrameConfig::startOfflineParse); connect(ui.pb_realParse, &QPushButton::clicked, this, &FrameConfig::startRealParse); // 进度条 ui.pb_progressBar->setRange(0, 100); ui.pb_progressBar->setValue(0); ui.le_networkIP->setText("225.0.0.151"); ui.le_networkPort->setText("11511"); } FrameConfig::~FrameConfig() {} void FrameConfig::initModelType() { ui.cb_modelType->clear(); ui.cb_modelType->addItem("请选择产品型号!"); connect(ui.cb_modelType, &QComboBox::currentTextChanged, this, &FrameConfig::selectModelType); } void FrameConfig::initNetworkType() { ui.cb_networkType->clear(); ui.cb_networkType->addItem("请选择网络类型!"); ui.cb_networkType->addItem("UDP组播"); ui.cb_networkType->addItem("UDP单播"); connect(ui.cb_networkType, &QComboBox::currentTextChanged, this, &FrameConfig::selectNetworkType); } void FrameConfig::initStatusInfo() { m_pStatusInfoModel = new QStandardItemModel(this); m_pStatusInfoModel->setColumnCount(3); m_pStatusInfoModel->setHorizontalHeaderLabels({"序号", "时间", "事件"}); ui.tv_statusInfo->setModel(m_pStatusInfoModel); ui.tv_statusInfo->setColumnWidth(0, 60); ui.tv_statusInfo->setColumnWidth(1, 150); ui.tv_statusInfo->setColumnWidth(2, 200); ui.tv_statusInfo->header()->setDefaultAlignment(Qt::AlignLeft); // 设置表头居中 ui.tv_statusInfo->header()->hide(); } void FrameConfig::displayStatusInfo(bool isSucess, QString statusInfo) { int rowCount = m_pStatusInfoModel->rowCount(); QStandardItem* itemNum = new QStandardItem(QString::number(rowCount + 1)); QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); QStandardItem* itemTime = new QStandardItem(strTime); // 时间 QStandardItem* itemInfo = new QStandardItem(statusInfo); // 信息 m_pStatusInfoModel->setItem(rowCount, 0, itemNum); m_pStatusInfoModel->setItem(rowCount, 1, itemTime); m_pStatusInfoModel->setItem(rowCount, 2, itemInfo); if (isSucess == false) { m_pStatusInfoModel->item(rowCount, 0)->setForeground(QBrush(QColor(255, 0, 0))); // 红色 m_pStatusInfoModel->item(rowCount, 1)->setForeground(QBrush(QColor(255, 0, 0))); m_pStatusInfoModel->item(rowCount, 2)->setForeground(QBrush(QColor(255, 0, 0))); } else { m_pStatusInfoModel->item(rowCount, 0)->setForeground(QBrush(QColor(0, 0, 0))); // 黑色 m_pStatusInfoModel->item(rowCount, 1)->setForeground(QBrush(QColor(0, 0, 0))); m_pStatusInfoModel->item(rowCount, 2)->setForeground(QBrush(QColor(0, 0, 0))); } for (int i = 0; i < 3; i++) { // m_pStatusInfoModel->item(rowCount, i)->setTextAlignment(Qt::AlignHCenter | // Qt::AlignLeft); m_pStatusInfoModel->item(rowCount, i)->setTextAlignment(Qt::AlignLeft); } ui.tv_statusInfo->scrollToBottom(); // 滚动到底部 } void FrameConfig::loadConfigFiles() { if (m_bOfflineParse == true) { displayStatusInfo(false, "正在离线解析数据!"); return; } if (m_bRealParse == true) { displayStatusInfo(false, "正在实时解析数据!"); return; } initModelType(); m_configFilesList.clear(); m_mapStrConfigInfo.clear(); m_strExePath = m_pSingleton->getExePath(); QString strDir = m_strExePath + "/Config/"; QDir dir(strDir); QStringList fileFilters; fileFilters << "*.xml"; // 遍历目录下所有满足条件的文件名 QStringList configFiles = dir.entryList(fileFilters, QDir::Files | QDir::Readable, QDir::Name); // 获取所有目录名称列表 for (QString fileName : configFiles) { QStringList strSplitList = fileName.split("."); QString strSuffix = strSplitList.at(strSplitList.length() - 1); QString strValidName = fileName.mid(0, fileName.length() - strSuffix.length() - 1); // 读取配置文件 if (!readConfigFile(strDir, fileName, strValidName)) { continue; } ui.cb_modelType->addItem(strValidName); m_configFilesList.append(strValidName); } QMutexLocker locker(&m_mutex); m_pSingleton->setConfigInfo(m_mapStrConfigInfo); } bool FrameConfig::readConfigFile(QString strdir, QString strfile, QString strvalid) { QFile file(strdir + strfile); if (!file.open(QIODevice::ReadOnly)) { return false; } QDomDocument domDoc; if (!domDoc.setContent(&file)) { file.close(); return false; } file.close(); ConfigInfo* configInfo = new ConfigInfo(); configInfo->m_strValidName = strvalid; QDomElement rootElement = domDoc.documentElement(); // 返回根节点 QDomElement frameElement = rootElement.firstChildElement("FrameInfo").firstChildElement("Frame"); // 返回根节点的子节点 if (!frameElement.isNull()) { Frame* pFrame = new Frame(); pFrame->m_strHead = frameElement.attribute("head"); // 解析帧头 char cHead[2] = {0x00, 0x00}; unsigned short usHead = pFrame->m_strHead.toUShort(nullptr, 16); memcpy(cHead, (char*)&usHead + 1, 1); memcpy(cHead + 1, (char*)&usHead, 1); pFrame->m_headArray = QByteArray(cHead, 2); pFrame->m_usSubFrameType = frameElement.attribute("subFrameType").toUShort(); if (pFrame->m_usSubFrameType == 2) { // 反码副帧 // 求反码副帧帧头 unsigned short usTemp = 0xFFFF; unsigned short usSubHead = ~(usHead & usTemp); memcpy(cHead, (char*)&usSubHead + 1, 1); memcpy(cHead + 1, (char*)&usSubHead, 1); pFrame->m_subHeadArray = QByteArray(cHead, 2); } pFrame->m_usHeadAddr = frameElement.attribute("headAddr").toUShort(); pFrame->m_usIdAddr = frameElement.attribute("idAddr").toUShort(); pFrame->m_usIdStart = frameElement.attribute("idStart").toUShort(); pFrame->m_uiRow = frameElement.attribute("row").toUInt(); pFrame->m_uiColumn = frameElement.attribute("column").toUInt(); pFrame->m_dFrameTime = frameElement.attribute("frameTime").toDouble(); // 帧间隔 pFrame->m_usIdEnd = pFrame->m_usIdStart + pFrame->m_uiRow - 1; // 计算帧长 pFrame->m_uiFrameLen = pFrame->m_uiRow * pFrame->m_uiColumn; switch (pFrame->m_usHeadAddr) { case 1: // 帧头在每行最前 pFrame->m_usBeforeHeadLen = 0; break; case 2: // 帧头在每行最后 pFrame->m_usBeforeHeadLen = pFrame->m_uiColumn - 2; break; default: break; } configInfo->m_pFrame = pFrame; } QDomElement paramElement = rootElement.firstChildElement("ParamInfo").firstChildElement("Param"); // 返回根节点的子节点 while (!paramElement.isNull()) { Param* param = new Param(); param->m_uiId = paramElement.attribute("id").toUInt(); param->m_strCode = paramElement.attribute("code"); param->m_strTitle = paramElement.attribute("title"); param->m_strChannelGroup = paramElement.attribute("channelGroup"); param->m_pChannelGroup = new ChannelGroup(); // 对通道进行拆分 QString strChannelGroup = param->m_strChannelGroup; channelDeal(configInfo->m_pFrame, param, strChannelGroup); param->m_usModel = paramElement.attribute("model").toUShort(); if (param->m_usModel == 3) { // 图像 param->m_usFormat = paramElement.attribute("format").toUShort(); // 原始图像格式 param->m_uiWidth = paramElement.attribute("width").toUInt(); // 一帧图像像素宽度 param->m_uiHeight = paramElement.attribute("height").toUInt(); // 一帧图像像素高度 } if (param->m_usModel == 2 || param->m_usModel == 3) { // 数字量和图像 if (paramElement.hasAttribute("fill")) { param->m_strFill = paramElement.attribute("fill"); } } else if (param->m_usModel == 1 || param->m_usModel == 4) { // 模拟量和状态量 param->m_strFill = ""; } // 获取填充值 char cFill = 0x00; QString strFill = param->m_strFill; // 剔除0x if (strFill.contains("0x")) { strFill = strFill.remove("0x"); } unsigned short usFill = 0; for (int i = 0; i < strFill.size(); i += 2) { unsigned short usFill = strFill.mid(i, 2).toUShort(nullptr, 16); memcpy(&cFill, (char*)&usFill, 1); param->m_fillArray.append(cFill); } param->m_usType = paramElement.attribute("type").toUShort(); param->m_usOrder = paramElement.attribute("order").toUShort(); param->m_strBit = paramElement.attribute("bit"); param->m_strFormula = paramElement.attribute("formula"); // 坐标公式处理 if (param->m_strFormula != "") { formulaDeal(param); } param->m_strUnit = paramElement.attribute("unit"); configInfo->m_mapUIntParam.insert(std::pair(param->m_uiId, param)); paramElement = paramElement.nextSiblingElement(); } m_mapStrConfigInfo.insert(std::pair(configInfo->m_strValidName, configInfo)); return true; } void FrameConfig::channelDeal(Frame* frame, Param* param, QString channelGroup) { if (channelGroup.contains( ";", Qt::CaseInsensitive)) { // 包含";",可能是分段连续列、分段单列、分段单坐标 if (channelGroup.contains("~") && channelGroup.contains("Col-")) { // 说明存在连续列 for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理 QStringList strChannelList = channelGroup.split(";"); for (int j = 0; j < strChannelList.size(); j++) { QString strTemp = strChannelList.at(j); QStringList strTempList = strTemp.split("~"); QString strStart = strTempList.at(0); // 第一个 QString strEnd = strTempList.at(1); // 最后一个 unsigned int uiStart = 0; unsigned int uiEnd = 0; uiStart = strStart.split("-").at(1).toUInt(); uiEnd = strEnd.split("-").at(1).toUInt(); for (unsigned int k = uiStart; k <= uiEnd; k++) { Channel* pChannel = new Channel(); pChannel->m_uiMinorFrame = i; pChannel->m_uiSubFrame = k; pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + k; // 绝对位置 param->m_pChannelGroup->m_vecChannel.push_back(pChannel); } } } param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size(); } else if (!channelGroup.contains("~") && channelGroup.contains("Col-")) { // 说明包含列,但不包含连续列 for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理 QStringList strChannelList = channelGroup.split(";"); for (int j = 0; j < strChannelList.size(); j++) { QString strTemp = strChannelList.at(j); unsigned int uiColumn = strTemp.split("-").at(1).toUInt(); Channel* pChannel = new Channel(); pChannel->m_uiMinorFrame = i; pChannel->m_uiSubFrame = uiColumn; pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + uiColumn; // 绝对位置 param->m_pChannelGroup->m_vecChannel.push_back(pChannel); } } param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size(); } else if (!channelGroup.contains("~") && !channelGroup.contains("Col-") && channelGroup.contains("#")) { // 说明为单坐标 QStringList strChannelList = channelGroup.split(";"); for (int i = 0; i < strChannelList.size(); i++) { QString strTemp = strChannelList.at(i); QStringList strTempList = strTemp.split("#"); QStringList strLeftList = strTempList.at(0).split(","); // 行 QStringList strRightList = strTempList.at(1).split(","); // 列 unsigned int uiRow = 0; unsigned int uiColumn = 0; for (unsigned int i = 0; i < strLeftList.size(); i++) { uiRow = strLeftList.at(i).toUInt(); for (unsigned int j = 0; j < strRightList.size(); j++) { uiColumn = strRightList.at(j).toUInt(); Channel* pChannel = new Channel(); pChannel->m_uiMinorFrame = uiRow; pChannel->m_uiSubFrame = uiColumn; pChannel->m_uiAbsolutePos = frame->m_uiColumn * uiRow + uiColumn; param->m_pChannelGroup->m_vecChannel.push_back(pChannel); } } param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size(); } } } else { // 不包含";",可能是连续列、单列、单坐标 if (channelGroup.contains("~") && channelGroup.contains("Col-")) { // 说明存在连续列 for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理 QStringList strTempList = channelGroup.split("~"); QString strStart = strTempList.at(0); // 第一个 QString strEnd = strTempList.at(1); // 最后一个 unsigned int uiStart = 0; unsigned int uiEnd = 0; uiStart = strStart.split("-").at(1).toUInt(); uiEnd = strEnd.split("-").at(1).toUInt(); for (unsigned int k = uiStart; k <= uiEnd; k++) { Channel* pChannel = new Channel(); pChannel->m_uiMinorFrame = i; pChannel->m_uiSubFrame = k; pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + k; // 绝对位置 param->m_pChannelGroup->m_vecChannel.push_back(pChannel); } } param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size(); } else if (!channelGroup.contains("~") && channelGroup.contains("Col-")) { // 说明包含列,但不包含连续列 for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理 unsigned int uiColumn = channelGroup.split("-").at(1).toUInt(); Channel* pChannel = new Channel(); pChannel->m_uiMinorFrame = i; pChannel->m_uiSubFrame = uiColumn; pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + uiColumn; // 绝对位置 param->m_pChannelGroup->m_vecChannel.push_back(pChannel); } param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size(); } else if (!channelGroup.contains("~") && !channelGroup.contains("Col-") && channelGroup.contains("#")) { // 说明为单坐标 QStringList strTempList = channelGroup.split("#"); QStringList strLeftList = strTempList.at(0).split(","); // 行 QStringList strRightList = strTempList.at(1).split(","); // 列 unsigned int uiRow = 0; unsigned int uiColumn = 0; for (unsigned int i = 0; i < strLeftList.size(); i++) { uiRow = strLeftList.at(i).toUInt(); for (unsigned int j = 0; j < strRightList.size(); j++) { uiColumn = strRightList.at(j).toUInt(); Channel* pChannel = new Channel(); pChannel->m_uiMinorFrame = uiRow; pChannel->m_uiSubFrame = uiColumn; pChannel->m_uiAbsolutePos = frame->m_uiColumn * uiRow + uiColumn; param->m_pChannelGroup->m_vecChannel.push_back(pChannel); } } param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size(); } } } void FrameConfig::formulaDeal(Param* param) { // 利用正则表达式对公式进行匹配 QRegExp regFormula("^\\[((-?\\d+)|((-?\\d+)(\\.\\d+)))(,((-?\\d+)|((-?\\d+)(\\.\\d+))))*\\]$"); if (regFormula.exactMatch(param->m_strFormula)) { int iStart = param->m_strFormula.indexOf("[") + 1; int iEnd = param->m_strFormula.indexOf("]"); QString strValid = param->m_strFormula.mid(iStart, iEnd - iStart); QStringList strList = strValid.split(","); int equaNum = strList.size() - 1; // 最高次方 param->m_formula.equaNum = equaNum; for (int i = 0; i < strList.size(); i++) { param->m_formula.Equation[i] = strList.at(equaNum - i).toDouble(); } } } void FrameConfig::selectModelType() { if (m_bOfflineParse == true) { displayStatusInfo(false, "正在离线解析数据!"); return; } if (m_bRealParse == true) { displayStatusInfo(false, "正在实时解析数据!"); return; } m_strModelType = ui.cb_modelType->currentText(); if (m_strModelType == "请选择产品型号!") { return; } m_pSingleton->setModelType(m_strModelType); emit switchModelType(m_strModelType); } void FrameConfig::selectNetworkType() { if (ui.cb_networkType->currentText() == "请选择网络类型!") { return; } QRegExp ipExp( "\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-" "9]?)\\b"); QRegExp portExp( "^([0-9]|[1-9]\\d|[1-9]\\d{2}|[1-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]" "\\d|6553[0-5])$"); // 判断IP地址和端口号 QString strIP = ui.le_networkIP->text(); // IP地址 QString strPort = ui.le_networkPort->text(); // 端口号 bool bIpExp = ipExp.exactMatch(strIP); bool bPortExp = portExp.exactMatch(strPort); if (!bIpExp || !bPortExp) { displayStatusInfo(false, "IP地址或端口号有误!"); return; } QHostAddress hostAddress = QHostAddress(strIP); QString strNetworkType = ui.cb_networkType->currentText(); if (strNetworkType == "UDP单播") { m_network.type = 1; } else if (strNetworkType == "UDP组播") { if (!hostAddress.isMulticast()) { displayStatusInfo(false, "组播地址设置有误!"); return; } m_network.type = 2; } m_network.ip = strIP; m_network.port = strPort.toUShort(); } void FrameConfig::startOfflineParse() { if (ui.cb_modelType->currentText() == "请选择产品型号!") { displayStatusInfo(false, "请选择产品型号!"); return; } if (m_bRealParse == true) { displayStatusInfo(false, "正在实时解析数据!"); return; } if (m_bOfflineParse == false) { QString fileName = QFileDialog::getOpenFileName(this, QObject::tr("请选择数据文件"), strFileDir, "*.*;;*.bin;;*.dat"); if (fileName == "") { return; } m_bOfflineParse = true; m_uiParseStatus = 1; // 离线解析 ui.pb_offlineParse->setText("停止"); displayStatusInfo(true, "开始离线解析数据!"); int pos = fileName.lastIndexOf("/"); strFileDir = fileName.left(pos); QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { return; } QByteArray byteArray = file.readAll(); startAfterProc(byteArray); } else if (m_bOfflineParse == true) { stopAfterProc(); m_bOfflineParse = false; m_uiParseStatus = 0; ui.pb_offlineParse->setText("离线解析"); displayStatusInfo(true, "离线解析数据结束!"); } emit parseStatus(m_uiParseStatus); } void FrameConfig::startAfterProc(QByteArray byteArray) { createDataPath(m_uiParseStatus); map::iterator mapIter; mapIter = m_mapStrConfigInfo.begin(); while (mapIter != m_mapStrConfigInfo.end()) { if ((*mapIter).first != m_strModelType) { ++mapIter; continue; } ValidAfterProc* m_pValidAfterProc = new ValidAfterProc(); connect(m_pValidAfterProc, &ValidAfterProc::validDataExtract, this, &FrameConfig::validDataExtract); connect(m_pValidAfterProc, &ValidAfterProc::finished, m_pValidAfterProc, &ValidAfterProc::deleteLater); m_pValidAfterProc->init((*mapIter).second->m_pFrame); m_pValidAfterProc->setData(byteArray); m_pValidAfterProc->start(); ++mapIter; } } // 按变量个数进行提取 void FrameConfig::validDataExtract(QByteArray byteArray) { displayStatusInfo(true, "开始解析数据!"); ui.pb_progressBar->setValue(0); m_uiDataProcFinished = 0; auto mapIter = m_mapStrConfigInfo.find(m_strModelType); if (mapIter != m_mapStrConfigInfo.end()) { // 针对每个参数建立一个数据处理线程 m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size(); for (auto param : mapIter->second->m_mapUIntParam) { if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量 CurveWidget* curveWidget = param.second->getCurveWidget(); curveWidget->clearWidget(); curveWidget->m_bRefTime = false; AnalogAfterProc* pAnalogAfterProc = new AnalogAfterProc(); connect(pAnalogAfterProc, &AnalogAfterProc::parseFinished, curveWidget, &CurveWidget::parseFinished); connect(pAnalogAfterProc, &AnalogAfterProc::finished, this, &FrameConfig::dataProcFinished); connect(pAnalogAfterProc, &AnalogAfterProc::finished, pAnalogAfterProc, &AnalogAfterProc::deleteLater); pAnalogAfterProc->init(mapIter->second->m_pFrame, param); pAnalogAfterProc->setData(byteArray); pAnalogAfterProc->start(); } else if (param.second->m_usModel == 2) { // 数字量 DigitalAfterProc* pDigitalAfterProc = new DigitalAfterProc(); connect(pDigitalAfterProc, &DigitalAfterProc::finished, this, &FrameConfig::dataProcFinished); connect(pDigitalAfterProc, &DigitalAfterProc::finished, pDigitalAfterProc, &DigitalAfterProc::deleteLater); pDigitalAfterProc->init(mapIter->second->m_pFrame, param); pDigitalAfterProc->setData(byteArray); pDigitalAfterProc->start(); } else if (param.second->m_usModel == 3) { // 图像 VideoAfterProc* pVideoAfterProc = new VideoAfterProc(); connect(pVideoAfterProc, &VideoAfterProc::dataProcFinished, this, &FrameConfig::dataProcFinished); connect(pVideoAfterProc, &VideoAfterProc::finished, pVideoAfterProc, &VideoAfterProc::deleteLater); pVideoAfterProc->init(mapIter->second->m_pFrame, param); pVideoAfterProc->getFfmpegDecode(); VideoWidget* videoWidget = param.second->getVideoWidget(); if (videoWidget != nullptr) { // 建立播放窗口与视频数据解析线程之间的关系 connect(videoWidget, &VideoWidget::startPlayer, pVideoAfterProc, &VideoAfterProc::startPlayer); connect(videoWidget, &VideoWidget::videoSpeed, pVideoAfterProc, &VideoAfterProc::videoSpeed); connect(videoWidget, &VideoWidget::setPlayPos, pVideoAfterProc, &VideoAfterProc::setPlayPos); connect(pVideoAfterProc, &VideoAfterProc::playedCount, videoWidget, &VideoWidget::playedCount); } pVideoAfterProc->setData(byteArray); pVideoAfterProc->start(); m_mapUIntAfterProc.insert(std::make_pair(param.second->m_uiId, pVideoAfterProc)); } } } } void FrameConfig::dataProcFinished() { ++m_uiDataProcFinished; if (m_uiDataProcFinished < m_uiDataProcNum) { int value = (int)((m_uiDataProcFinished * 1.0 / m_uiDataProcNum * 1.0) * 100.0); ui.pb_progressBar->setValue(value); return; } ui.pb_progressBar->setValue(100); displayStatusInfo(true, "提取数据结束!"); } void FrameConfig::stopAfterProc() { // 停止视频窗口播放 auto mapIter = m_mapStrConfigInfo.find(m_strModelType); if (mapIter != m_mapStrConfigInfo.end()) { m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size(); for (auto param : mapIter->second->m_mapUIntParam) { if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量 } else if (param.second->m_usModel == 3) { // 图像 param.second->getVideoWidget()->stopPlay(); } } } for (auto afterproc : m_mapUIntAfterProc) { // 关闭数据解析 afterproc.second->stop(); } m_mapUIntAfterProc.clear(); ui.pb_progressBar->setValue(0); } void FrameConfig::startRealParse() { if (ui.cb_modelType->currentText() == "请选择产品型号!") { displayStatusInfo(false, "请选择产品型号!"); return; } if (ui.cb_networkType->currentText() == "请选择网络类型!") { displayStatusInfo(false, "请选择网络类型!"); return; } if (m_bOfflineParse == true) { displayStatusInfo(false, "正在离线解析数据!"); return; } if (m_bRealParse == false) { m_bRealParse = true; m_uiParseStatus = 2; // 在线解析 ui.pb_realParse->setText("停止"); displayStatusInfo(true, "开始实时解析数据!"); selectNetworkType(); startProcess(); } else if (m_bRealParse == true) { stopProcess(); m_bRealParse = false; m_uiParseStatus = 0; ui.pb_realParse->setText("实时解析"); displayStatusInfo(true, "实时解析数据结束!"); } emit parseStatus(m_uiParseStatus); } void FrameConfig::startProcess() { createDataPath(m_uiParseStatus); Frame* pFrame = nullptr; auto mapIter = m_mapStrConfigInfo.find(m_strModelType); if (mapIter != m_mapStrConfigInfo.end()) { m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size(); for (auto param : mapIter->second->m_mapUIntParam) { pFrame = mapIter->second->m_pFrame; if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量 CurveWidget* curveWidget = param.second->getCurveWidget(); curveWidget->clearWidget(); curveWidget->startRefresh(true); curveWidget->m_bRefTime = false; AnalogProcess* pAnalogProcess = new AnalogProcess(); connect(pAnalogProcess, &AnalogProcess::finished, pAnalogProcess, &AnalogProcess::deleteLater); pAnalogProcess->init(mapIter->second->m_pFrame, param); pAnalogProcess->start(); m_mapUIntProcess.insert(std::make_pair(param.second->m_uiId, pAnalogProcess)); } else if (param.second->m_usModel == 2) { // 数字量 DigitalProcess* pDigitalProcess = new DigitalProcess(); connect(pDigitalProcess, &DigitalProcess::finished, pDigitalProcess, &DigitalProcess::deleteLater); pDigitalProcess->init(mapIter->second->m_pFrame, param); pDigitalProcess->start(); m_mapUIntProcess.insert(std::make_pair(param.second->m_uiId, pDigitalProcess)); } else if (param.second->m_usModel == 3) { // 图像 VideoWidget* videoWidget = param.second->getVideoWidget(); videoWidget->clearWidget(); VideoProcess* pVideoProcess = new VideoProcess(); connect(pVideoProcess, &VideoProcess::finished, pVideoProcess, &VideoProcess::deleteLater); pVideoProcess->init(mapIter->second->m_pFrame, param); pVideoProcess->getFfmpegDecode(); if (videoWidget != nullptr) { // 建立播放窗口与视频数据解析线程之间的关系 connect(videoWidget, &VideoWidget::startPlayer, pVideoProcess, &VideoProcess::startPlayer); // connect(pVideoProcess, &VideoProcess::playedCount, videoWidget, // &VideoWidget::playedCount); } pVideoProcess->start(); m_mapUIntProcess.insert(std::make_pair(param.second->m_uiId, pVideoProcess)); } } m_pValidProcess = new ValidProcess(); connect(m_pValidProcess, &ValidProcess::finished, m_pValidProcess, &ValidProcess::deleteLater); m_pValidProcess->init(mapIter->second->m_pFrame, m_mapUIntProcess); m_pValidProcess->start(); } m_pNetDataRecv = new NetDataRecv(); connect(m_pNetDataRecv, &NetDataRecv::finished, m_pNetDataRecv, &NetDataRecv::deleteLater); m_pNetDataRecv->init(pFrame, m_network, m_pValidProcess); m_pNetDataRecv->start(); } void FrameConfig::stopProcess() { auto mapIter = m_mapStrConfigInfo.find(m_strModelType); if (mapIter != m_mapStrConfigInfo.end()) { m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size(); for (auto param : mapIter->second->m_mapUIntParam) { if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量 param.second->getCurveWidget()->startRefresh(false); // 停止曲线界面刷新 } else if (param.second->m_usModel == 3) { // 图像 param.second->getVideoWidget()->stopPlay(); // 停止图像窗口播放 } } } if (m_pNetDataRecv) { // 关闭网络接收 m_pNetDataRecv->stop(); m_pNetDataRecv->quit(); m_pNetDataRecv->wait(); delete m_pNetDataRecv; m_pNetDataRecv = nullptr; } if (m_pValidProcess) { // 关闭缓存处理 m_pValidProcess->stop(); m_pValidProcess->quit(); m_pValidProcess->wait(); delete m_pValidProcess; m_pValidProcess = nullptr; } for (auto process : m_mapUIntProcess) { // 关闭数据解析 process.second->stop(); process.second->quit(); process.second->wait(); delete process.second; process.second = nullptr; } m_mapUIntProcess.clear(); } void FrameConfig::createDataPath(unsigned int status) { QString strStatus = ""; if (status == 1) { // 离线解析 strStatus = "Offline"; } else if (status == 2) { // 实时解析 strStatus = "Real"; } // 根据时间建立数据存储路径 QString strDateTime = QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss"); m_strDataPath = m_strExePath + "/Data/" + m_strModelType + "_" + strStatus + "_" + strDateTime; auto succ = QDir(m_strDataPath).mkpath("."); m_pSingleton->setDataPath(m_strDataPath); // 创建数据存储文件 auto mapIter = m_mapStrConfigInfo.find(m_strModelType); if (mapIter != m_mapStrConfigInfo.end()) { mapIter->second->m_pFrame->m_dataStore.m_strStoreType = strStatus; // 存储类型 mapIter->second->m_pFrame->m_dataStore.m_strDateTime = strDateTime; // 存储日期 mapIter->second->m_pFrame->m_dataStore.m_strDataPath = m_strDataPath; // 数据存储路径 } }