You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

FrameConfig.cpp 34 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. #include "FrameConfig.h"
  2. #include <utility> /**< std::pair std::make_pair */
  3. #include <QDir>
  4. #include <QMessageBox>
  5. FrameConfig::FrameConfig(QWidget* parent)
  6. : QWidget(parent)
  7. , m_pSingleton(nullptr)
  8. , m_strExePath("")
  9. , m_strDataPath("")
  10. , m_strModelType("")
  11. , m_pStatusInfoModel(nullptr)
  12. , strFileDir(".\\")
  13. , m_pValidProcess(nullptr)
  14. , m_pNetDataRecv(nullptr)
  15. , m_uiDataProcFinished(0)
  16. , m_uiDataProcNum(0)
  17. , m_bOfflineParse(false) // 是否正在进行离线解析
  18. , m_bRealParse(false) // 是否正在进行实时解析
  19. , m_uiParseStatus(0)
  20. {
  21. ui.setupUi(this);
  22. m_pSingleton = Singleton::CreateInstance();
  23. m_mapUIntAfterProc.clear();
  24. m_mapUIntProcess.clear();
  25. initNetworkType(); // 初始化网络选择
  26. loadConfigFiles(); // 加载XML配置文件
  27. initStatusInfo(); // 初始化状态信息
  28. connect(ui.pb_loadFile, &QPushButton::clicked, this, &FrameConfig::loadConfigFiles);
  29. connect(ui.pb_offlineParse, &QPushButton::clicked, this, &FrameConfig::startOfflineParse);
  30. connect(ui.pb_realParse, &QPushButton::clicked, this, &FrameConfig::startRealParse);
  31. // 进度条
  32. ui.pb_progressBar->setRange(0, 100);
  33. ui.pb_progressBar->setValue(0);
  34. ui.le_networkIP->setText("225.0.0.151");
  35. ui.le_networkPort->setText("11511");
  36. }
  37. FrameConfig::~FrameConfig()
  38. {}
  39. void FrameConfig::initModelType()
  40. {
  41. ui.cb_modelType->clear();
  42. ui.cb_modelType->addItem("请选择产品型号!");
  43. connect(ui.cb_modelType, &QComboBox::currentTextChanged, this, &FrameConfig::selectModelType);
  44. }
  45. void FrameConfig::initNetworkType()
  46. {
  47. ui.cb_networkType->clear();
  48. ui.cb_networkType->addItem("请选择网络类型!");
  49. ui.cb_networkType->addItem("UDP组播");
  50. ui.cb_networkType->addItem("UDP单播");
  51. connect(ui.cb_networkType, &QComboBox::currentTextChanged, this,
  52. &FrameConfig::selectNetworkType);
  53. }
  54. void FrameConfig::initStatusInfo()
  55. {
  56. m_pStatusInfoModel = new QStandardItemModel(this);
  57. m_pStatusInfoModel->setColumnCount(3);
  58. m_pStatusInfoModel->setHorizontalHeaderLabels({"序号", "时间", "事件"});
  59. ui.tv_statusInfo->setModel(m_pStatusInfoModel);
  60. ui.tv_statusInfo->setColumnWidth(0, 60);
  61. ui.tv_statusInfo->setColumnWidth(1, 150);
  62. ui.tv_statusInfo->setColumnWidth(2, 200);
  63. ui.tv_statusInfo->header()->setDefaultAlignment(Qt::AlignLeft); // 设置表头居中
  64. ui.tv_statusInfo->header()->hide();
  65. }
  66. void FrameConfig::displayStatusInfo(bool isSucess, QString statusInfo)
  67. {
  68. int rowCount = m_pStatusInfoModel->rowCount();
  69. QStandardItem* itemNum = new QStandardItem(QString::number(rowCount + 1));
  70. QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
  71. QStandardItem* itemTime = new QStandardItem(strTime); // 时间
  72. QStandardItem* itemInfo = new QStandardItem(statusInfo); // 信息
  73. m_pStatusInfoModel->setItem(rowCount, 0, itemNum);
  74. m_pStatusInfoModel->setItem(rowCount, 1, itemTime);
  75. m_pStatusInfoModel->setItem(rowCount, 2, itemInfo);
  76. if (isSucess == false) {
  77. m_pStatusInfoModel->item(rowCount, 0)->setForeground(QBrush(QColor(255, 0, 0))); // 红色
  78. m_pStatusInfoModel->item(rowCount, 1)->setForeground(QBrush(QColor(255, 0, 0)));
  79. m_pStatusInfoModel->item(rowCount, 2)->setForeground(QBrush(QColor(255, 0, 0)));
  80. } else {
  81. m_pStatusInfoModel->item(rowCount, 0)->setForeground(QBrush(QColor(0, 0, 0))); // 黑色
  82. m_pStatusInfoModel->item(rowCount, 1)->setForeground(QBrush(QColor(0, 0, 0)));
  83. m_pStatusInfoModel->item(rowCount, 2)->setForeground(QBrush(QColor(0, 0, 0)));
  84. }
  85. for (int i = 0; i < 3; i++) {
  86. // m_pStatusInfoModel->item(rowCount, i)->setTextAlignment(Qt::AlignHCenter |
  87. // Qt::AlignLeft);
  88. m_pStatusInfoModel->item(rowCount, i)->setTextAlignment(Qt::AlignLeft);
  89. }
  90. ui.tv_statusInfo->scrollToBottom(); // 滚动到底部
  91. }
  92. void FrameConfig::loadConfigFiles()
  93. {
  94. if (m_bOfflineParse == true) {
  95. displayStatusInfo(false, "正在离线解析数据!");
  96. return;
  97. }
  98. if (m_bRealParse == true) {
  99. displayStatusInfo(false, "正在实时解析数据!");
  100. return;
  101. }
  102. initModelType();
  103. m_configFilesList.clear();
  104. m_mapStrConfigInfo.clear();
  105. m_strExePath = m_pSingleton->getExePath();
  106. QString strDir = m_strExePath + "/Config/";
  107. QDir dir(strDir);
  108. QStringList fileFilters;
  109. fileFilters << "*.xml";
  110. // 遍历目录下所有满足条件的文件名
  111. QStringList configFiles = dir.entryList(fileFilters, QDir::Files | QDir::Readable,
  112. QDir::Name); // 获取所有目录名称列表
  113. for (QString fileName : configFiles) {
  114. QStringList strSplitList = fileName.split(".");
  115. QString strSuffix = strSplitList.at(strSplitList.length() - 1);
  116. QString strValidName = fileName.mid(0, fileName.length() - strSuffix.length() - 1);
  117. // 读取配置文件
  118. if (!readConfigFile(strDir, fileName, strValidName)) {
  119. continue;
  120. }
  121. ui.cb_modelType->addItem(strValidName);
  122. m_configFilesList.append(strValidName);
  123. }
  124. QMutexLocker locker(&m_mutex);
  125. m_pSingleton->setConfigInfo(m_mapStrConfigInfo);
  126. }
  127. bool FrameConfig::readConfigFile(QString strdir, QString strfile, QString strvalid)
  128. {
  129. QFile file(strdir + strfile);
  130. if (!file.open(QIODevice::ReadOnly)) {
  131. return false;
  132. }
  133. QDomDocument domDoc;
  134. if (!domDoc.setContent(&file)) {
  135. file.close();
  136. return false;
  137. }
  138. file.close();
  139. ConfigInfo* configInfo = new ConfigInfo();
  140. configInfo->m_strValidName = strvalid;
  141. QDomElement rootElement = domDoc.documentElement(); // 返回根节点
  142. QDomElement frameElement =
  143. rootElement.firstChildElement("FrameInfo").firstChildElement("Frame"); // 返回根节点的子节点
  144. if (!frameElement.isNull()) {
  145. Frame* pFrame = new Frame();
  146. pFrame->m_strHead = frameElement.attribute("head");
  147. // 解析帧头
  148. char cHead[2] = {0x00, 0x00};
  149. unsigned short usHead = pFrame->m_strHead.toUShort(nullptr, 16);
  150. memcpy(cHead, (char*)&usHead + 1, 1);
  151. memcpy(cHead + 1, (char*)&usHead, 1);
  152. pFrame->m_headArray = QByteArray(cHead, 2);
  153. pFrame->m_usSubFrameType = frameElement.attribute("subFrameType").toUShort();
  154. if (pFrame->m_usSubFrameType == 2) { // 反码副帧
  155. // 求反码副帧帧头
  156. unsigned short usTemp = 0xFFFF;
  157. unsigned short usSubHead = ~(usHead & usTemp);
  158. memcpy(cHead, (char*)&usSubHead + 1, 1);
  159. memcpy(cHead + 1, (char*)&usSubHead, 1);
  160. pFrame->m_subHeadArray = QByteArray(cHead, 2);
  161. }
  162. pFrame->m_usHeadAddr = frameElement.attribute("headAddr").toUShort();
  163. pFrame->m_usIdAddr = frameElement.attribute("idAddr").toUShort();
  164. pFrame->m_usIdStart = frameElement.attribute("idStart").toUShort();
  165. pFrame->m_uiRow = frameElement.attribute("row").toUInt();
  166. pFrame->m_uiColumn = frameElement.attribute("column").toUInt();
  167. pFrame->m_dFrameTime = frameElement.attribute("frameTime").toDouble(); // 帧间隔
  168. pFrame->m_usIdEnd = pFrame->m_usIdStart + pFrame->m_uiRow - 1;
  169. // 计算帧长
  170. pFrame->m_uiFrameLen = pFrame->m_uiRow * pFrame->m_uiColumn;
  171. switch (pFrame->m_usHeadAddr) {
  172. case 1: // 帧头在每行最前
  173. pFrame->m_usBeforeHeadLen = 0;
  174. break;
  175. case 2: // 帧头在每行最后
  176. pFrame->m_usBeforeHeadLen = pFrame->m_uiColumn - 2;
  177. break;
  178. default:
  179. break;
  180. }
  181. configInfo->m_pFrame = pFrame;
  182. }
  183. QDomElement paramElement =
  184. rootElement.firstChildElement("ParamInfo").firstChildElement("Param"); // 返回根节点的子节点
  185. while (!paramElement.isNull()) {
  186. Param* param = new Param();
  187. param->m_uiId = paramElement.attribute("id").toUInt();
  188. param->m_strCode = paramElement.attribute("code");
  189. param->m_strTitle = paramElement.attribute("title");
  190. param->m_strChannelGroup = paramElement.attribute("channelGroup");
  191. param->m_pChannelGroup = new ChannelGroup();
  192. // 对通道进行拆分
  193. QString strChannelGroup = param->m_strChannelGroup;
  194. channelDeal(configInfo->m_pFrame, param, strChannelGroup);
  195. param->m_usModel = paramElement.attribute("model").toUShort();
  196. if (param->m_usModel == 3) { // 图像
  197. param->m_usFormat = paramElement.attribute("format").toUShort(); // 原始图像格式
  198. param->m_uiWidth = paramElement.attribute("width").toUInt(); // 一帧图像像素宽度
  199. param->m_uiHeight = paramElement.attribute("height").toUInt(); // 一帧图像像素高度
  200. }
  201. if (param->m_usModel == 2 || param->m_usModel == 3) { // 数字量和图像
  202. if (paramElement.hasAttribute("fill")) {
  203. param->m_strFill = paramElement.attribute("fill");
  204. }
  205. } else if (param->m_usModel == 1 || param->m_usModel == 4) { // 模拟量和状态量
  206. param->m_strFill = "";
  207. }
  208. // 获取填充值
  209. char cFill = 0x00;
  210. QString strFill = param->m_strFill;
  211. // 剔除0x
  212. if (strFill.contains("0x")) {
  213. strFill = strFill.remove("0x");
  214. }
  215. unsigned short usFill = 0;
  216. for (int i = 0; i < strFill.size(); i += 2) {
  217. unsigned short usFill = strFill.mid(i, 2).toUShort(nullptr, 16);
  218. memcpy(&cFill, (char*)&usFill, 1);
  219. param->m_fillArray.append(cFill);
  220. }
  221. param->m_usType = paramElement.attribute("type").toUShort();
  222. param->m_usOrder = paramElement.attribute("order").toUShort();
  223. param->m_strBit = paramElement.attribute("bit");
  224. param->m_strFormula = paramElement.attribute("formula");
  225. // 坐标公式处理
  226. if (param->m_strFormula != "") {
  227. formulaDeal(param);
  228. }
  229. param->m_strUnit = paramElement.attribute("unit");
  230. configInfo->m_mapUIntParam.insert(std::pair<unsigned int, Param*>(param->m_uiId, param));
  231. paramElement = paramElement.nextSiblingElement();
  232. }
  233. m_mapStrConfigInfo.insert(std::pair<QString, ConfigInfo*>(configInfo->m_strValidName, configInfo));
  234. return true;
  235. }
  236. void FrameConfig::channelDeal(Frame* frame, Param* param, QString channelGroup)
  237. {
  238. if (channelGroup.contains(
  239. ";", Qt::CaseInsensitive)) { // 包含";",可能是分段连续列、分段单列、分段单坐标
  240. if (channelGroup.contains("~") && channelGroup.contains("Col-")) { // 说明存在连续列
  241. for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理
  242. QStringList strChannelList = channelGroup.split(";");
  243. for (int j = 0; j < strChannelList.size(); j++) {
  244. QString strTemp = strChannelList.at(j);
  245. QStringList strTempList = strTemp.split("~");
  246. QString strStart = strTempList.at(0); // 第一个
  247. QString strEnd = strTempList.at(1); // 最后一个
  248. unsigned int uiStart = 0;
  249. unsigned int uiEnd = 0;
  250. uiStart = strStart.split("-").at(1).toUInt();
  251. uiEnd = strEnd.split("-").at(1).toUInt();
  252. for (unsigned int k = uiStart; k <= uiEnd; k++) {
  253. Channel* pChannel = new Channel();
  254. pChannel->m_uiMinorFrame = i;
  255. pChannel->m_uiSubFrame = k;
  256. pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + k; // 绝对位置
  257. param->m_pChannelGroup->m_vecChannel.push_back(pChannel);
  258. }
  259. }
  260. }
  261. param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size();
  262. } else if (!channelGroup.contains("~")
  263. && channelGroup.contains("Col-")) { // 说明包含列,但不包含连续列
  264. for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理
  265. QStringList strChannelList = channelGroup.split(";");
  266. for (int j = 0; j < strChannelList.size(); j++) {
  267. QString strTemp = strChannelList.at(j);
  268. unsigned int uiColumn = strTemp.split("-").at(1).toUInt();
  269. Channel* pChannel = new Channel();
  270. pChannel->m_uiMinorFrame = i;
  271. pChannel->m_uiSubFrame = uiColumn;
  272. pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + uiColumn; // 绝对位置
  273. param->m_pChannelGroup->m_vecChannel.push_back(pChannel);
  274. }
  275. }
  276. param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size();
  277. } else if (!channelGroup.contains("~") && !channelGroup.contains("Col-")
  278. && channelGroup.contains("#")) { // 说明为单坐标
  279. QStringList strChannelList = channelGroup.split(";");
  280. for (int i = 0; i < strChannelList.size(); i++) {
  281. QString strTemp = strChannelList.at(i);
  282. QStringList strTempList = strTemp.split("#");
  283. QStringList strLeftList = strTempList.at(0).split(","); // 行
  284. QStringList strRightList = strTempList.at(1).split(","); // 列
  285. unsigned int uiRow = 0;
  286. unsigned int uiColumn = 0;
  287. for (unsigned int i = 0; i < strLeftList.size(); i++) {
  288. uiRow = strLeftList.at(i).toUInt();
  289. for (unsigned int j = 0; j < strRightList.size(); j++) {
  290. uiColumn = strRightList.at(j).toUInt();
  291. Channel* pChannel = new Channel();
  292. pChannel->m_uiMinorFrame = uiRow;
  293. pChannel->m_uiSubFrame = uiColumn;
  294. pChannel->m_uiAbsolutePos = frame->m_uiColumn * uiRow + uiColumn;
  295. param->m_pChannelGroup->m_vecChannel.push_back(pChannel);
  296. }
  297. }
  298. param->m_pChannelGroup->m_uiChannelNum =
  299. param->m_pChannelGroup->m_vecChannel.size();
  300. }
  301. }
  302. } else { // 不包含";",可能是连续列、单列、单坐标
  303. if (channelGroup.contains("~") && channelGroup.contains("Col-")) { // 说明存在连续列
  304. for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理
  305. QStringList strTempList = channelGroup.split("~");
  306. QString strStart = strTempList.at(0); // 第一个
  307. QString strEnd = strTempList.at(1); // 最后一个
  308. unsigned int uiStart = 0;
  309. unsigned int uiEnd = 0;
  310. uiStart = strStart.split("-").at(1).toUInt();
  311. uiEnd = strEnd.split("-").at(1).toUInt();
  312. for (unsigned int k = uiStart; k <= uiEnd; k++) {
  313. Channel* pChannel = new Channel();
  314. pChannel->m_uiMinorFrame = i;
  315. pChannel->m_uiSubFrame = k;
  316. pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + k; // 绝对位置
  317. param->m_pChannelGroup->m_vecChannel.push_back(pChannel);
  318. }
  319. }
  320. param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size();
  321. } else if (!channelGroup.contains("~")
  322. && channelGroup.contains("Col-")) { // 说明包含列,但不包含连续列
  323. for (unsigned int i = 0; i < frame->m_uiRow; i++) { // 对每一行进行处理
  324. unsigned int uiColumn = channelGroup.split("-").at(1).toUInt();
  325. Channel* pChannel = new Channel();
  326. pChannel->m_uiMinorFrame = i;
  327. pChannel->m_uiSubFrame = uiColumn;
  328. pChannel->m_uiAbsolutePos = frame->m_uiColumn * i + uiColumn; // 绝对位置
  329. param->m_pChannelGroup->m_vecChannel.push_back(pChannel);
  330. }
  331. param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size();
  332. } else if (!channelGroup.contains("~") && !channelGroup.contains("Col-")
  333. && channelGroup.contains("#")) { // 说明为单坐标
  334. QStringList strTempList = channelGroup.split("#");
  335. QStringList strLeftList = strTempList.at(0).split(","); // 行
  336. QStringList strRightList = strTempList.at(1).split(","); // 列
  337. unsigned int uiRow = 0;
  338. unsigned int uiColumn = 0;
  339. for (unsigned int i = 0; i < strLeftList.size(); i++) {
  340. uiRow = strLeftList.at(i).toUInt();
  341. for (unsigned int j = 0; j < strRightList.size(); j++) {
  342. uiColumn = strRightList.at(j).toUInt();
  343. Channel* pChannel = new Channel();
  344. pChannel->m_uiMinorFrame = uiRow;
  345. pChannel->m_uiSubFrame = uiColumn;
  346. pChannel->m_uiAbsolutePos = frame->m_uiColumn * uiRow + uiColumn;
  347. param->m_pChannelGroup->m_vecChannel.push_back(pChannel);
  348. }
  349. }
  350. param->m_pChannelGroup->m_uiChannelNum = param->m_pChannelGroup->m_vecChannel.size();
  351. }
  352. }
  353. }
  354. void FrameConfig::formulaDeal(Param* param)
  355. {
  356. // 利用正则表达式对公式进行匹配
  357. QRegExp regFormula("^\\[((-?\\d+)|((-?\\d+)(\\.\\d+)))(,((-?\\d+)|((-?\\d+)(\\.\\d+))))*\\]$");
  358. if (regFormula.exactMatch(param->m_strFormula)) {
  359. int iStart = param->m_strFormula.indexOf("[") + 1;
  360. int iEnd = param->m_strFormula.indexOf("]");
  361. QString strValid = param->m_strFormula.mid(iStart, iEnd - iStart);
  362. QStringList strList = strValid.split(",");
  363. int equaNum = strList.size() - 1; // 最高次方
  364. param->m_formula.equaNum = equaNum;
  365. for (int i = 0; i < strList.size(); i++) {
  366. param->m_formula.Equation[i] = strList.at(equaNum - i).toDouble();
  367. }
  368. }
  369. }
  370. void FrameConfig::selectModelType()
  371. {
  372. if (m_bOfflineParse == true) {
  373. displayStatusInfo(false, "正在离线解析数据!");
  374. return;
  375. }
  376. if (m_bRealParse == true) {
  377. displayStatusInfo(false, "正在实时解析数据!");
  378. return;
  379. }
  380. m_strModelType = ui.cb_modelType->currentText();
  381. if (m_strModelType == "请选择产品型号!") {
  382. return;
  383. }
  384. m_pSingleton->setModelType(m_strModelType);
  385. emit switchModelType(m_strModelType);
  386. }
  387. void FrameConfig::selectNetworkType()
  388. {
  389. if (ui.cb_networkType->currentText() == "请选择网络类型!") {
  390. return;
  391. }
  392. QRegExp ipExp(
  393. "\\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-"
  394. "9]?)\\b");
  395. QRegExp portExp(
  396. "^([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]"
  397. "\\d|6553[0-5])$");
  398. // 判断IP地址和端口号
  399. QString strIP = ui.le_networkIP->text(); // IP地址
  400. QString strPort = ui.le_networkPort->text(); // 端口号
  401. bool bIpExp = ipExp.exactMatch(strIP);
  402. bool bPortExp = portExp.exactMatch(strPort);
  403. if (!bIpExp || !bPortExp) {
  404. displayStatusInfo(false, "IP地址或端口号有误!");
  405. return;
  406. }
  407. QHostAddress hostAddress = QHostAddress(strIP);
  408. QString strNetworkType = ui.cb_networkType->currentText();
  409. if (strNetworkType == "UDP单播") {
  410. m_network.type = 1;
  411. } else if (strNetworkType == "UDP组播") {
  412. if (!hostAddress.isMulticast()) {
  413. displayStatusInfo(false, "组播地址设置有误!");
  414. return;
  415. }
  416. m_network.type = 2;
  417. }
  418. m_network.ip = strIP;
  419. m_network.port = strPort.toUShort();
  420. }
  421. void FrameConfig::startOfflineParse()
  422. {
  423. if (ui.cb_modelType->currentText() == "请选择产品型号!") {
  424. displayStatusInfo(false, "请选择产品型号!");
  425. return;
  426. }
  427. if (m_bRealParse == true) {
  428. displayStatusInfo(false, "正在实时解析数据!");
  429. return;
  430. }
  431. if (m_bOfflineParse == false) {
  432. QString fileName = QFileDialog::getOpenFileName(this, QObject::tr("请选择数据文件"),
  433. strFileDir, "*.*;;*.bin;;*.dat");
  434. if (fileName == "") {
  435. return;
  436. }
  437. m_bOfflineParse = true;
  438. m_uiParseStatus = 1; // 离线解析
  439. ui.pb_offlineParse->setText("停止");
  440. displayStatusInfo(true, "开始离线解析数据!");
  441. int pos = fileName.lastIndexOf("/");
  442. strFileDir = fileName.left(pos);
  443. QFile file(fileName);
  444. if (!file.open(QIODevice::ReadOnly)) {
  445. return;
  446. }
  447. QByteArray byteArray = file.readAll();
  448. startAfterProc(byteArray);
  449. } else if (m_bOfflineParse == true) {
  450. stopAfterProc();
  451. m_bOfflineParse = false;
  452. m_uiParseStatus = 0;
  453. ui.pb_offlineParse->setText("离线解析");
  454. displayStatusInfo(true, "离线解析数据结束!");
  455. }
  456. emit parseStatus(m_uiParseStatus);
  457. }
  458. void FrameConfig::startAfterProc(QByteArray byteArray)
  459. {
  460. createDataPath(m_uiParseStatus);
  461. map<QString, ConfigInfo*>::iterator mapIter;
  462. mapIter = m_mapStrConfigInfo.begin();
  463. while (mapIter != m_mapStrConfigInfo.end()) {
  464. if ((*mapIter).first != m_strModelType) {
  465. ++mapIter;
  466. continue;
  467. }
  468. ValidAfterProc* m_pValidAfterProc = new ValidAfterProc();
  469. connect(m_pValidAfterProc, &ValidAfterProc::validDataExtract, this,
  470. &FrameConfig::validDataExtract);
  471. connect(m_pValidAfterProc, &ValidAfterProc::finished, m_pValidAfterProc,
  472. &ValidAfterProc::deleteLater);
  473. m_pValidAfterProc->init((*mapIter).second->m_pFrame);
  474. m_pValidAfterProc->setData(byteArray);
  475. m_pValidAfterProc->start();
  476. ++mapIter;
  477. }
  478. }
  479. // 按变量个数进行提取
  480. void FrameConfig::validDataExtract(QByteArray byteArray)
  481. {
  482. displayStatusInfo(true, "开始解析数据!");
  483. ui.pb_progressBar->setValue(0);
  484. m_uiDataProcFinished = 0;
  485. auto mapIter = m_mapStrConfigInfo.find(m_strModelType);
  486. if (mapIter != m_mapStrConfigInfo.end()) {
  487. // 针对每个参数建立一个数据处理线程
  488. m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size();
  489. for (auto param : mapIter->second->m_mapUIntParam) {
  490. if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量
  491. CurveWidget* curveWidget = param.second->getCurveWidget();
  492. curveWidget->clearWidget();
  493. curveWidget->m_bRefTime = false;
  494. AnalogAfterProc* pAnalogAfterProc = new AnalogAfterProc();
  495. connect(pAnalogAfterProc, &AnalogAfterProc::parseFinished, curveWidget,
  496. &CurveWidget::parseFinished);
  497. connect(pAnalogAfterProc, &AnalogAfterProc::finished, this,
  498. &FrameConfig::dataProcFinished);
  499. connect(pAnalogAfterProc, &AnalogAfterProc::finished, pAnalogAfterProc,
  500. &AnalogAfterProc::deleteLater);
  501. pAnalogAfterProc->init(mapIter->second->m_pFrame, param);
  502. pAnalogAfterProc->setData(byteArray);
  503. pAnalogAfterProc->start();
  504. } else if (param.second->m_usModel == 2) { // 数字量
  505. DigitalAfterProc* pDigitalAfterProc = new DigitalAfterProc();
  506. connect(pDigitalAfterProc, &DigitalAfterProc::finished, this,
  507. &FrameConfig::dataProcFinished);
  508. connect(pDigitalAfterProc, &DigitalAfterProc::finished, pDigitalAfterProc,
  509. &DigitalAfterProc::deleteLater);
  510. pDigitalAfterProc->init(mapIter->second->m_pFrame, param);
  511. pDigitalAfterProc->setData(byteArray);
  512. pDigitalAfterProc->start();
  513. } else if (param.second->m_usModel == 3) { // 图像
  514. VideoAfterProc* pVideoAfterProc = new VideoAfterProc();
  515. connect(pVideoAfterProc, &VideoAfterProc::dataProcFinished, this,
  516. &FrameConfig::dataProcFinished);
  517. connect(pVideoAfterProc, &VideoAfterProc::finished, pVideoAfterProc,
  518. &VideoAfterProc::deleteLater);
  519. pVideoAfterProc->init(mapIter->second->m_pFrame, param);
  520. pVideoAfterProc->getFfmpegDecode();
  521. VideoWidget* videoWidget = param.second->getVideoWidget();
  522. if (videoWidget != nullptr) {
  523. // 建立播放窗口与视频数据解析线程之间的关系
  524. connect(videoWidget, &VideoWidget::startPlayer, pVideoAfterProc,
  525. &VideoAfterProc::startPlayer);
  526. connect(videoWidget, &VideoWidget::videoSpeed, pVideoAfterProc,
  527. &VideoAfterProc::videoSpeed);
  528. connect(videoWidget, &VideoWidget::setPlayPos, pVideoAfterProc,
  529. &VideoAfterProc::setPlayPos);
  530. connect(pVideoAfterProc, &VideoAfterProc::playedCount, videoWidget,
  531. &VideoWidget::playedCount);
  532. }
  533. pVideoAfterProc->setData(byteArray);
  534. pVideoAfterProc->start();
  535. m_mapUIntAfterProc.insert(std::make_pair(param.second->m_uiId, pVideoAfterProc));
  536. }
  537. }
  538. }
  539. }
  540. void FrameConfig::dataProcFinished()
  541. {
  542. ++m_uiDataProcFinished;
  543. if (m_uiDataProcFinished < m_uiDataProcNum) {
  544. int value = (int)((m_uiDataProcFinished * 1.0 / m_uiDataProcNum * 1.0) * 100.0);
  545. ui.pb_progressBar->setValue(value);
  546. return;
  547. }
  548. ui.pb_progressBar->setValue(100);
  549. displayStatusInfo(true, "提取数据结束!");
  550. }
  551. void FrameConfig::stopAfterProc()
  552. {
  553. // 停止视频窗口播放
  554. auto mapIter = m_mapStrConfigInfo.find(m_strModelType);
  555. if (mapIter != m_mapStrConfigInfo.end()) {
  556. m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size();
  557. for (auto param : mapIter->second->m_mapUIntParam) {
  558. if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量
  559. } else if (param.second->m_usModel == 3) { // 图像
  560. param.second->getVideoWidget()->stopPlay();
  561. }
  562. }
  563. }
  564. for (auto afterproc : m_mapUIntAfterProc) { // 关闭数据解析
  565. afterproc.second->stop();
  566. }
  567. m_mapUIntAfterProc.clear();
  568. ui.pb_progressBar->setValue(0);
  569. }
  570. void FrameConfig::startRealParse()
  571. {
  572. if (ui.cb_modelType->currentText() == "请选择产品型号!") {
  573. displayStatusInfo(false, "请选择产品型号!");
  574. return;
  575. }
  576. if (ui.cb_networkType->currentText() == "请选择网络类型!") {
  577. displayStatusInfo(false, "请选择网络类型!");
  578. return;
  579. }
  580. if (m_bOfflineParse == true) {
  581. displayStatusInfo(false, "正在离线解析数据!");
  582. return;
  583. }
  584. if (m_bRealParse == false) {
  585. m_bRealParse = true;
  586. m_uiParseStatus = 2; // 在线解析
  587. ui.pb_realParse->setText("停止");
  588. displayStatusInfo(true, "开始实时解析数据!");
  589. selectNetworkType();
  590. startProcess();
  591. } else if (m_bRealParse == true) {
  592. stopProcess();
  593. m_bRealParse = false;
  594. m_uiParseStatus = 0;
  595. ui.pb_realParse->setText("实时解析");
  596. displayStatusInfo(true, "实时解析数据结束!");
  597. }
  598. emit parseStatus(m_uiParseStatus);
  599. }
  600. void FrameConfig::startProcess()
  601. {
  602. createDataPath(m_uiParseStatus);
  603. Frame* pFrame = nullptr;
  604. auto mapIter = m_mapStrConfigInfo.find(m_strModelType);
  605. if (mapIter != m_mapStrConfigInfo.end()) {
  606. m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size();
  607. for (auto param : mapIter->second->m_mapUIntParam) {
  608. pFrame = mapIter->second->m_pFrame;
  609. if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量
  610. CurveWidget* curveWidget = param.second->getCurveWidget();
  611. curveWidget->clearWidget();
  612. curveWidget->startRefresh(true);
  613. curveWidget->m_bRefTime = false;
  614. AnalogProcess* pAnalogProcess = new AnalogProcess();
  615. connect(pAnalogProcess, &AnalogProcess::finished, pAnalogProcess,
  616. &AnalogProcess::deleteLater);
  617. pAnalogProcess->init(mapIter->second->m_pFrame, param);
  618. pAnalogProcess->start();
  619. m_mapUIntProcess.insert(std::make_pair(param.second->m_uiId, pAnalogProcess));
  620. } else if (param.second->m_usModel == 2) { // 数字量
  621. DigitalProcess* pDigitalProcess = new DigitalProcess();
  622. connect(pDigitalProcess, &DigitalProcess::finished, pDigitalProcess,
  623. &DigitalProcess::deleteLater);
  624. pDigitalProcess->init(mapIter->second->m_pFrame, param);
  625. pDigitalProcess->start();
  626. m_mapUIntProcess.insert(std::make_pair(param.second->m_uiId, pDigitalProcess));
  627. } else if (param.second->m_usModel == 3) { // 图像
  628. VideoWidget* videoWidget = param.second->getVideoWidget();
  629. videoWidget->clearWidget();
  630. VideoProcess* pVideoProcess = new VideoProcess();
  631. connect(pVideoProcess, &VideoProcess::finished, pVideoProcess,
  632. &VideoProcess::deleteLater);
  633. pVideoProcess->init(mapIter->second->m_pFrame, param);
  634. pVideoProcess->getFfmpegDecode();
  635. if (videoWidget != nullptr) {
  636. // 建立播放窗口与视频数据解析线程之间的关系
  637. connect(videoWidget, &VideoWidget::startPlayer, pVideoProcess,
  638. &VideoProcess::startPlayer);
  639. // connect(pVideoProcess, &VideoProcess::playedCount, videoWidget,
  640. // &VideoWidget::playedCount);
  641. }
  642. pVideoProcess->start();
  643. m_mapUIntProcess.insert(std::make_pair(param.second->m_uiId, pVideoProcess));
  644. }
  645. }
  646. m_pValidProcess = new ValidProcess();
  647. connect(m_pValidProcess, &ValidProcess::finished, m_pValidProcess,
  648. &ValidProcess::deleteLater);
  649. m_pValidProcess->init(mapIter->second->m_pFrame, m_mapUIntProcess);
  650. m_pValidProcess->start();
  651. }
  652. m_pNetDataRecv = new NetDataRecv();
  653. connect(m_pNetDataRecv, &NetDataRecv::finished, m_pNetDataRecv, &NetDataRecv::deleteLater);
  654. m_pNetDataRecv->init(pFrame, m_network, m_pValidProcess);
  655. m_pNetDataRecv->start();
  656. }
  657. void FrameConfig::stopProcess()
  658. {
  659. auto mapIter = m_mapStrConfigInfo.find(m_strModelType);
  660. if (mapIter != m_mapStrConfigInfo.end()) {
  661. m_uiDataProcNum = (unsigned int)mapIter->second->m_mapUIntParam.size();
  662. for (auto param : mapIter->second->m_mapUIntParam) {
  663. if (param.second->m_usModel == 1 || param.second->m_usModel == 4) { // 工程量或状态量
  664. param.second->getCurveWidget()->startRefresh(false); // 停止曲线界面刷新
  665. } else if (param.second->m_usModel == 3) { // 图像
  666. param.second->getVideoWidget()->stopPlay(); // 停止图像窗口播放
  667. }
  668. }
  669. }
  670. if (m_pNetDataRecv) { // 关闭网络接收
  671. m_pNetDataRecv->stop();
  672. m_pNetDataRecv->quit();
  673. m_pNetDataRecv->wait();
  674. delete m_pNetDataRecv;
  675. m_pNetDataRecv = nullptr;
  676. }
  677. if (m_pValidProcess) { // 关闭缓存处理
  678. m_pValidProcess->stop();
  679. m_pValidProcess->quit();
  680. m_pValidProcess->wait();
  681. delete m_pValidProcess;
  682. m_pValidProcess = nullptr;
  683. }
  684. for (auto process : m_mapUIntProcess) { // 关闭数据解析
  685. process.second->stop();
  686. process.second->quit();
  687. process.second->wait();
  688. delete process.second;
  689. process.second = nullptr;
  690. }
  691. m_mapUIntProcess.clear();
  692. }
  693. void FrameConfig::createDataPath(unsigned int status)
  694. {
  695. QString strStatus = "";
  696. if (status == 1) { // 离线解析
  697. strStatus = "Offline";
  698. } else if (status == 2) { // 实时解析
  699. strStatus = "Real";
  700. }
  701. // 根据时间建立数据存储路径
  702. QString strDateTime = QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss");
  703. m_strDataPath = m_strExePath + "/Data/" + m_strModelType + "_" + strStatus + "_" + strDateTime;
  704. auto succ = QDir(m_strDataPath).mkpath(".");
  705. m_pSingleton->setDataPath(m_strDataPath);
  706. // 创建数据存储文件
  707. auto mapIter = m_mapStrConfigInfo.find(m_strModelType);
  708. if (mapIter != m_mapStrConfigInfo.end()) {
  709. mapIter->second->m_pFrame->m_dataStore.m_strStoreType = strStatus; // 存储类型
  710. mapIter->second->m_pFrame->m_dataStore.m_strDateTime = strDateTime; // 存储日期
  711. mapIter->second->m_pFrame->m_dataStore.m_strDataPath = m_strDataPath; // 数据存储路径
  712. }
  713. }