From b8880f4da7573e1877f2ebb6e6d2bdf06d251f19 Mon Sep 17 00:00:00 2001 From: "Mr.V" Date: Tue, 30 Apr 2024 14:51:41 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E8=BF=9E=E4=B8=B2=E5=8F=A3=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/qt_source/mainwindow.cpp | 533 ++++++---------------------------- src/qt_source/mainwindow.h | 59 ++-- src/serial/ComDetect.cpp | 81 ++---- src/serial/ComDetect.h | 8 +- src/threads/ReadComThread.cpp | 61 ++-- src/threads/ReadComThread.h | 4 +- 6 files changed, 179 insertions(+), 567 deletions(-) diff --git a/src/qt_source/mainwindow.cpp b/src/qt_source/mainwindow.cpp index b60b093..c3df802 100644 --- a/src/qt_source/mainwindow.cpp +++ b/src/qt_source/mainwindow.cpp @@ -15,13 +15,12 @@ MainWindow::MainWindow(QWidget *parent) this->statusBar = new QStatusBar(); this->statusInfo = new QLabel("初始化完成",this); this->statusBar->addPermanentWidget(this->statusInfo);//显示正常信息 - QLabel* statusVersion = new QLabel("开启时间:" + QDateTime::currentDateTime().toString("yy-MM-dd hh:mm"),this); + QLabel* statusVersion = new QLabel("开启时间:" + QDateTime::currentDateTime().toString("yy.MM.dd.hh.mm"),this); this->statusBar->addWidget(statusVersion); layout()->addWidget(this->statusBar); this->setWindowTitle("Matrix_RFID 车号识别程序(勿关!!)"); - this->configPath_ = "./config/config.ini"; if (!this->mkLogDir()) { @@ -30,15 +29,7 @@ MainWindow::MainWindow(QWidget *parent) // 配置文件读取 QString errorMessage = ""; - if (!ConfigUtil::readBaseConfig(this->configPath_, errorMessage, this->baseConfig_)) - { - this->logError(errorMessage); - } - if (!ConfigUtil::readInterfaceConfig(this->configPath_, errorMessage, this->interfaceConfig_)) - { - this->logError(errorMessage); - } - if (!ConfigUtil::readSocketServerConfig(this->configPath_, errorMessage, this->socketServerConfig_)) + if (!ConfigUtil::readBaseConfig(g_config_path, errorMessage, this->baseConfig_)) { this->logError(errorMessage); } @@ -49,27 +40,13 @@ MainWindow::MainWindow(QWidget *parent) // 初始化界面上的串口打开参数 this->initComboBox(); - this->serial_ = new QSerialPort; - - m_pSystemTray=new QSystemTrayIcon(this); connect(this->ui->openComButton, &QPushButton::clicked, this, &MainWindow::openComClicked); - - connect(this, &MainWindow::getRfid_signals, this, &MainWindow::getQueueDataThread); - - connect(this, &MainWindow::upRfid_signals, this, &MainWindow::upRfid); - connect(this->ui->testButton, &QPushButton::clicked, this, &MainWindow::readTestInfo); - // 识别状态改变 - connect(this, &MainWindow::IdentifyType, this, &MainWindow::IdentifyTypeUpdate); - //最小化信号槽 + + // 最小化信号槽 connect(m_pSystemTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason))); - - this->logRfidRecvName = "./Logs/rfid_data.txt"; - this->recvLog.setFileName(logRfidRecvName); - this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append); - //初始最小化 //this->showMinimized();//最小化 // 设置最大展示数据行数 @@ -80,91 +57,52 @@ MainWindow::MainWindow(QWidget *parent) this->ui->resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); this->ui->resultTable->verticalHeader()->setMinimumWidth(50); - if (!this->baseConfig_.upResult) - { - QIcon icon("./Fail.ico"); - QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 - this->ui->upflagLabel->setPixmap(m_pic); - }else{ - QIcon icon("./Succ.ico"); - QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 - this->ui->upflagLabel->setPixmap(m_pic); - } +// if (!this->baseConfig_.upResult) +// { +// QIcon icon("./Fail.ico"); +// QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 +// this->ui->upflagLabel->setPixmap(m_pic); +// }else{ +// QIcon icon("./Succ.ico"); +// QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 +// this->ui->upflagLabel->setPixmap(m_pic); +// } - if (this->baseConfig_.useSocketServer) - { - // 创建线程 - QThread *threadWork = new QThread; // 任务线程 + // 初始化LED指示灯 + this->upResultType(this->baseConfig_.upResult); - this->tcpClient = new TcpClient(this); - this->tcpClient->moveToThread(threadWork); + this->readComThread = new ReadComThread(&this->queueTrainInfo_, this); + this->readComThread->start(); - connect(this, &MainWindow::connect_socket, this->tcpClient, &TcpClient::connectToServer); - - // 子线程反馈 socket 到主线程 - connect(this->tcpClient, &TcpClient::socketComplete, this, [=](QTcpSocket* tcp, QString ip, quint16 port){ - this->tcp_ = tcp; - }); - - // 接收子线程的消息提示 - connect(this->tcpClient, &TcpClient::sendTcpInfoSignals, this, [=](const QString& info){ - this->logInfo(info); - this->statusInfo->setText(info); - if (info == "链接服务端超时" - || info == "未连接Socket服务器" - || info == "链接服务端失败" - || info == "服务端断开连接" - || info == "链接服务端失败") - { - this->videoHasTrain = false; - } - }); - // 接收子线程的TCP消息内容展示 - connect(this->tcpClient, &TcpClient::getTcpInfoSignals, this, [=](const QString& info){ - this->logInfo(info); - }); - - emit connect_socket(this->socketServerConfig_.server_ip, this->socketServerConfig_.server_port); - - connect(this->tcpClient, &TcpClient::comeTrainSignals, this, [=](bool type) { - if (type) - { - this->logInfo("视频车号识别-来车了"); - this->videoHasTrain = true; - emit IdentifyType(); - } - else - { - this->logInfo("视频车号识别-火车离开了"); - this->videoHasTrain = false; - if (this->needIdentify) - emit IdentifyType(); - } - }); - connect(this->tcpClient, &TcpClient::getDirectionSignals, this, [=](int direction) { - if (this->iDirection == 0) - { - this->logInfo("获得方向判定:" + QString(direction > -1 ? (direction > 0 ? "需识别" : "待定") : "无需上传")); - this->iDirection = direction; - } - }); - } - - ui->openComButton->click(); - - this->upResultThread = new UpResultThread(&this->queueTrainInfo_, &this->iDirection, this); + this->upResultThread = new UpResultThread(&this->queueTrainInfo_, this); this->upResultThread->start(); + connect(this, &MainWindow::openCom_signals, this->readComThread, &ReadComThread::openCom); + connect(this, &MainWindow::readTestRfid_signals, this->readComThread, &ReadComThread::readTestInfo); + + connect(this->readComThread, &ReadComThread::openComSuccess, this, &MainWindow::openComResult); + connect(this->readComThread, &ReadComThread::closeComSuccess, this, &MainWindow::closeComResult); + connect(this->readComThread, &ReadComThread::comeTrain, this, &MainWindow::comeTrain); + connect(this->readComThread, &ReadComThread::upResultType, this, &MainWindow::upResultType); + // 状态栏信息变化 + connect(this->readComThread, &ReadComThread::statusInfoUpdate, this, &MainWindow::statusInfoUpdate); + + connect(this->readComThread, &ReadComThread::DebugSignals, this, &MainWindow::DebugSlots); + connect(this->readComThread, &ReadComThread::InfoSignals, this, &MainWindow::InfoSlots); + connect(this->readComThread, &ReadComThread::WarnSignals, this, &MainWindow::WarnSlots); + connect(this->readComThread, &ReadComThread::ErrorSignals, this, &MainWindow::ErrorSlots); + connect(this->upResultThread, &UpResultThread::DebugSignals, this, &MainWindow::DebugSlots); connect(this->upResultThread, &UpResultThread::InfoSignals, this, &MainWindow::InfoSlots); connect(this->upResultThread, &UpResultThread::WarnSignals, this, &MainWindow::WarnSlots); connect(this->upResultThread, &UpResultThread::ErrorSignals, this, &MainWindow::ErrorSlots); + + ui->openComButton->click(); } MainWindow::~MainWindow() { this->logInfo("-- 程序退出 --"); - this->initParam(); delete ui; } @@ -184,16 +122,8 @@ void MainWindow::logError(const QString& message) { LogError << message.toStdString(); ui->textBrowser->append(QString("[Error] [") + this->getSystemTime() + QString::fromStdString("] ") + message); } - -void MainWindow::initParam() { - this->rfidSourceInfo = ""; - this->trainTime = ""; - if (this->recvLog.isOpen()) this->recvLog.close(); - this->vecTrain.clear(); - this->needIdentify = false; - this->rnameRfidLog(); - this->queue_.clear(); - this->iDirection = 0; +void MainWindow::statusInfoUpdate(const QString &info) { + this->statusInfo->setText(info); } /** @@ -212,80 +142,6 @@ bool MainWindow::mkLogDir() return true; } -bool MainWindow::mkRfidLog() -{ - try { - QFileInfo fileInfo(this->logRfidRecvName); - if(fileInfo.isFile()) - { - return true; - } - this->recvLog.setFileName(this->logRfidRecvName); - if (!this->recvLog.isOpen()) - { - this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append); - } - return true; - } catch (const std::exception &e) { - this->logError("创建、打开RFID原始数据日志文件失败,详细:"); - this->logError(e.what()); - } - return false; -} - -void MainWindow::deleteOldFiles(const QString &path, int days) -{ - QDir dir(path); - foreach(QFileInfo fi, dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) - { - if((fi.lastModified().addDays(days) < QDateTime::currentDateTime())) - { - QFile::remove(fi.absoluteFilePath()); - } - } -} - -bool MainWindow::rnameRfidLog() -{ - try { - this->recvLog.close(); - QFile logFile(this->logRfidRecvName); - QFileInfo fileInfo(logFile); - if (fileInfo.size() == 0) return false; - - QString newLogFileName = fileInfo.path() + "/"; - newLogFileName.append(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss")); - newLogFileName.append(".txt"); - - if (!logFile.rename(newLogFileName)) - { - this->logError("读取RFID原始数据,存储重命名失败!"); - return false; - } - - this->deleteOldFiles(fileInfo.path(), 3); - } catch (const std::exception &e) { - this->logError("读取RFID原始数据,存储重命名失败!"); - return false; - } - return true; -} - -void MainWindow::saveRfidLog(const QString &value) -{ - try { - QString logValue = value + "\n"; - if (!this->recvLog.isOpen()) - { - this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append); - } - this->recvLog.write(logValue.toUtf8()); - this->recvLog.flush(); - } catch (const std::exception &e) { - this->logError("保存RFID原数据失败"); - } -} - /** * 获取本地所有串口 * @return @@ -302,12 +158,13 @@ QList MainWindow::getComList() { /** * 初始化 comboxBox 组件的值 */ -void MainWindow::initComboBox() { +void MainWindow::initComboBox() +{ // ui->BTBox->setEditable(true); - ui->BTBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(225, 225, 225);}"); + ui->BTBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(255, 255, 255); color: rgb(225, 225, 225);}"); ui->BTBox->setView(new QListView()); ui->comBox->setEditable(true); - ui->comBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(225, 225, 225);}"); + ui->comBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(255, 255, 255); color: rgb(225, 225, 225);}"); ui->comBox->setMaxVisibleItems(5); ui->comBox->setView(new QListView()); ui->comBox->addItems(this->comList); @@ -325,9 +182,6 @@ void MainWindow::initComboBox() { ui->BTBox->setCurrentText(QString::number(this->baseConfig_.baud)); ui->truckEdit->setText(QString::number(this->baseConfig_.trackName)); - - this->rfidHasTrain = false; - this->videoHasTrain = false; } /** @@ -389,8 +243,6 @@ void MainWindow::closeEvent(QCloseEvent *event) // 验证账号和密码是否正确 if (password == "matrix") { - this->initParam(); - this->tcp_->close(); event->accept(); // 关闭窗口 exit(0); } else { @@ -458,31 +310,8 @@ void MainWindow::openComClicked() { if (ui->openComButton->text() == "打开串口") { - this->serial_ = this->comDetect_.openCom(ui->comBox->currentText(), ui->BTBox->currentIndex()); - if (this->serial_ != nullptr) - { - QString logs; - logs.append("串口打开成功\n"); - logs.append("串口号:" + ui->comBox->currentText() + "\n"); - logs.append("波特率:" + ui->BTBox->currentText() + "\n"); - if (this->baseConfig_.havaMagnetSteel) - logs.append("磁钢顺序:" + this->baseConfig_.magnetSteelOrder); - this->isOpenCom = true; - this->logInfo(logs); - this->ui->openComButton->setText("关闭串口"); - this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ " - "background-color: rgba(74, 221, 108, 225);\ " - "border:1px solid rgba(168, 168, 168, 105);"); - connect(this->serial_,&QSerialPort::readyRead,this,&MainWindow::readCom); // - - connect(this->serial_, &QSerialPort::errorOccurred, this, &MainWindow::serialPort_error); - - } - else - { - this->isOpenCom = false; - this->logInfo("串口打开失败!"); - } + this->auto_reconnect_serial_ = true; + emit openCom_signals(true); } else { @@ -491,232 +320,66 @@ void MainWindow::openComClicked() // 验证账号和密码是否正确 if (password == "matrix") { - if (this->comDetect_.closeCom()) - { - if (this->needIdentify == true) this->needIdentify = false; - this->isOpenCom = false; - this->logInfo("串口已关闭!"); - this->initParam(); - this->ui->openComButton->setText("打开串口"); - this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ " - "background-color: red;\ " - "border:1px solid rgba(168, 168, 168, 105);"); - } + this->auto_reconnect_serial_ = false; + + emit openCom_signals(false); } else { QMessageBox::warning(this, "验证失败", "密码不正确!"); } } } -/** - * 串口异常退出的槽函数 - * @param error - */ -void MainWindow::serialPort_error(QSerialPort::SerialPortError error) +void MainWindow::openComResult(const bool &success) { - if (error != QSerialPort::NoError) + this->ui->openComButton->setText("关闭串口"); + if (success) { - //关闭串口 - this->serial_->close(); - this->ui->openComButton->setText("打开串口"); - this->logError("串口异常退出,疑似接口松动"); - this->ui->LEDlabel->setStyleSheet("border-radius: 16px; \ " + this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ " + "background-color: rgba(74, 221, 108, 225);\ " + "border:1px solid rgba(168, 168, 168, 105);"); + } + else + { + this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ " "background-color: red;\ " "border:1px solid rgba(168, 168, 168, 105);"); + + this->logInfo("10秒钟后自动尝试重连串口..."); +// if (auto_reconnect_serial_) emit openCom_signals(true, 10 * 1000); + } +} + +void MainWindow::closeComResult(const bool &success) +{ + if (success) + { + this->ui->openComButton->setText("打开串口"); + this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ " + "background-color: red;\ " + "border:1px solid rgba(168, 168, 168, 105);"); + } + else + { + this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ " + "background-color: rgba(74, 221, 108, 225);\ " + "border:1px solid rgba(168, 168, 168, 105);"); } } -void MainWindow::readCom() -{ - try { - if (this->serial_->waitForReadyRead(10)) { - QByteArray data = this->serial_->readAll(); // 读取数据 - if(!data.isEmpty()) - { - this->queue_.push(QString(data)); - emit getRfid_signals(); - } -// this->serial_->clear(); - data.clear(); - } - else - { - this->logError("等待读取超时"); - } - } catch(...) { - this->logError("读取串口数据异常!"); - } +void MainWindow::comeTrain(const bool &success) { + this->resultTableModel_->clear(); + this->resultTableModel_ = this->getStandardItemModel(); } -/** - * @brief:从queue中获取数据 - * @param:空 - * @return:空 - */ -void MainWindow::getQueueDataThread() -{ - if (this->queue_.isEmpty()) return; - - QString strRfidInfo = this->queue_.getTop(); - this->queue_.pop(); - this->saveRfidLog(strRfidInfo); - this->tmpRfid.append(strRfidInfo); - if (this->tmpRfid.right(1) != "&") - { - return; - } - - this->tmpRfid = this->tmpRfid.replace("&", ""); - QStringList rfidSubList = this->tmpRfid.split("@"); - this->tmpRfid = ""; - - auto split_lambda = [=](QString strFirst, QString strOther){ - if (strFirst == "0") - { - this->rfidHasTrain = false; - this->logInfo("RFID-火车离开了"); - // 关功放信号 - // 需要结合 “来车状态”广播消息,确认是否真的车离开了; TODO:没有真离开,则向串口发送 @on& 避免关功放 - emit IdentifyType(); - } - else - { - // TODO: 此处按照4个磁钢来配置,可能存在一定限制; 另外逻辑需要优化 - if (strOther == "000000" // 第一次检测来车时(前提是上一次功放已关闭) - && (strFirst == this->baseConfig_.magnetSteelOrder.left(1) - || strFirst == this->baseConfig_.magnetSteelOrder.mid(1, 1))) - { - this->rfidHasTrain = true; - this->logInfo("RFID-来车了"); - emit IdentifyType(); - } - } - }; - - for (const auto & i : rfidSubList) - { - if (i.size() == 26 || i.size() == 24) - { - // 车厢信息 - QString strTrainInfo = i.mid(1,13); - - if (vecTrain.empty() || !vecTrain.contains(strTrainInfo)) - { - // 判断是否是车头 车头的第14位是 K或H (慎重) - if (!i.mid(14, 1).contains(QRegExp("^[0-9]+$"))) continue; - // 过滤掉车号中有非数字的 - if (!strTrainInfo.right(7).contains(QRegExp("^[0-9]+$"))) continue; - // 因信号不稳定 增加一行过滤 出现读到的编号数据里 空格替代了实际字符的情况 - if (strTrainInfo.right(7).simplified().size() < 7) continue; - - vecTrain.append(strTrainInfo); - int train_order = vecTrain.size(); - this->resultTableModel_->setItem(train_order - 1, 0, new QStandardItem(strTrainInfo)); - this->logInfo(QString("第%1节 %2").arg(train_order).arg(strTrainInfo)); - // 将接收到的RFID使用@符拼接起来,以待后续上传web - this->rfidSourceInfo.append("@" + i); - QString rfidinfo = this->rfidSourceInfo; - this->rfidSourceInfo = ""; - emit upRfid_signals(rfidinfo); - - } - } - else if (i.size() == 7) - { - // 不使用磁钢的情况下 过滤掉磁钢信号 - if (!this->baseConfig_.havaMagnetSteel) continue; - // 磁钢信号 - QString strFirst = i.left(1); - QString strOther = i.mid(1, i.size() - 1); - // 将接收到的RFID使用@符拼接起来,以待后续上传web - this->rfidSourceInfo.append("@" + i); - split_lambda(strFirst, strOther); - } - else if (i.size() == 14) // 特殊情况,来车信号少了&符 - { - // 不使用磁钢的情况下 过滤掉磁钢信号 - if (!this->baseConfig_.havaMagnetSteel) continue; - for (int j = 0; j < i.size(); j+=7) { - QString rfid_cg = i.mid(j, 7); - QString strFirst = rfid_cg.left(1); - QString strOther = rfid_cg.mid(1, 6); - // 将接收到的RFID使用@符拼接起来,以待后续上传web - this->rfidSourceInfo.append("@" + rfid_cg); - split_lambda(strFirst, strOther); - } - } - } -} - -void MainWindow::upRfid(QString rfidInfo) -{ - if (!this->baseConfig_.upResult) return; - if (!this->needIdentify && this->baseConfig_.havaMagnetSteel) - { - QIcon icon("./Fail.ico"); - QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 - this->ui->upflagLabel->setPixmap(m_pic); - return; - }else{ +void MainWindow::upResultType(const bool &type) { + if (type) { QIcon icon("./Succ.ico"); QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 this->ui->upflagLabel->setPixmap(m_pic); - } - - QString info = this->vecTrain.back(); - int order = this->vecTrain.size(); - - if (order > this->socketServerConfig_.delayed_upload && this->iDirection == 0) - { - this->iDirection = 1; - } - if (!this->baseConfig_.useSocketServer) this->iDirection = 1; - -// info = info.mid(1,info.size() - 1); - - TrainInfo trainInfo; - trainInfo.carriageType = info.left(6).simplified().toStdString(); - trainInfo.carriageNum = info.mid(6, info.size() - 6).simplified().toStdString(); - trainInfo.strOrder = QString::number(order).toStdString(); - trainInfo.trainTime = this->trainTime.toStdString(); - trainInfo.collectTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz").toStdString(); - trainInfo.strRfidInfo = rfidInfo.toStdString(); - -// this->queueTrainInfo_.push(trainInfo); - this->queueTmpTrainInfo_.push(trainInfo); - - if (this->iDirection < 0) - { - this->queueTmpTrainInfo_.clear(); - return; - } - if (this->iDirection > 0) - { - while (!this->queueTmpTrainInfo_.isEmpty()) - { - this->queueTrainInfo_.push(this->queueTmpTrainInfo_.pop()); - } - } -} - -void MainWindow::IdentifyTypeUpdate() { - if (this->rfidHasTrain || this->videoHasTrain) - { - if (!this->needIdentify) - { - this->logInfo("来车了"); - this->mkRfidLog(); - this->vecTrain.clear(); - this->needIdentify = true; - this->trainTime = this->getSystemTime(); - this->resultTableModel_->clear(); - this->resultTableModel_ = this->getStandardItemModel(); - } - } - else if (!this->rfidHasTrain && !this->videoHasTrain) - { - this->initParam(); - this->logInfo("火车离开了"); + } else { + QIcon icon("./Fail.ico"); + QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整 + this->ui->upflagLabel->setPixmap(m_pic); } } @@ -740,32 +403,16 @@ void MainWindow::ErrorSlots(const QString &info) { void MainWindow::readTestInfo() { - - if (this->isOpenCom || ui->openComButton->text() == "关闭串口") + if (this->ui->openComButton->text() == "关闭串口") { logWarn("请先关闭串口后进行测试操作!"); return; } QString filePath = QFileDialog::getOpenFileName(this, "选择一个文件", QDir::currentPath(), "(*.*)"); if(filePath.isEmpty()){ - QMessageBox::warning(this, "打开文件", "选择文件不能为空"); +// QMessageBox::warning(this, "打开文件", "选择文件不能为空"); return; } - // 创建一个QFile对象并打开要读取的文本文件 - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - logError("无法打开测试文件:" + filePath); - return; - } - logInfo("开始读取测试数据..."); - // 将文件内容读入到QStringList中 - QTextStream in(&file); - while(!in.atEnd()) { - QString line = in.readLine(); - this->queue_.push(line); - emit getRfid_signals(); - } - // 关闭文件 - file.close(); - logInfo("---读取测试数据完毕---"); + + emit this->readTestRfid_signals(filePath); } \ No newline at end of file diff --git a/src/qt_source/mainwindow.h b/src/qt_source/mainwindow.h index c0ab5ed..2a94a71 100644 --- a/src/qt_source/mainwindow.h +++ b/src/qt_source/mainwindow.h @@ -49,10 +49,11 @@ #include #include #include "common.h" -#include "ConfigUtil.h" -#include "ComDetect.h" -#include "TcpClient.h" -#include "../threads/UpResultThread.h" + +//#include "ComDetect.h" + +#include "UpResultThread.h" +#include "ReadComThread.h" QT_BEGIN_NAMESPACE @@ -62,7 +63,7 @@ using namespace ai_matrix; class MainWindow : public QWidget { - Q_OBJECT +Q_OBJECT public: MainWindow(QWidget *parent = nullptr); @@ -73,16 +74,10 @@ public: void logWarn(const QString& message); void logError(const QString& message); // 创建日志目录 - static bool mkLogDir(); - bool mkRfidLog(); - void deleteOldFiles(const QString &path, int days); - bool rnameRfidLog(); - void saveRfidLog(const QString &value); + bool mkLogDir(); void initParam(); - - QString getSystemTime(); // 获const 取串口列表& @@ -97,7 +92,7 @@ public: private: UpResultThread *upResultThread; - QString trainTime; + ReadComThread *readComThread; QString logRfidRecvName; QFile recvLog; @@ -105,41 +100,31 @@ private: QString configPath_; // ai_matrix::BaseConfig baseConfig_; ai_matrix::InterfaceConfig interfaceConfig_; - ai_matrix::SServerConfig socketServerConfig_; - std::string webToken; //授权信息 - QSerialPort *serial_; //串口 + std::string webToken; //授权信息 // 表格model QStandardItemModel *resultTableModel_ = nullptr; // 打开com口标志 bool isOpenCom = false; + bool auto_reconnect_serial_ = false; // Com口数据读取类 - ComDetect comDetect_; +// ComDetect comDetect_; // com口列表 QList comList; // 整列车识别结果存储 QStringList vecTrain; MQueue queue_{}; // RFID读取的数据队列 MQueue queueTrainInfo_{}; // RFID读取的磁钢信息队列 + QString rfidSourceInfo; QString tmpRfid; //临时存储的RFID原始数据,用于防止接收的数据不完整 - // 识别方向正确标志 - bool needIdentify = false; - // 视频识别有火车标志(使用socket服务时才有用) - bool videoHasTrain = false; - // RFID识别有火车标志 - bool rfidHasTrain = false; - // 是否是需要识别的方向 -1:不识别 0:未确定 1:识别 - int iDirection = 0; // 获取当前时间 QDateTime currentTime_ = QDateTime::currentDateTime(); - TcpClient* tcpClient; - private: - QTcpSocket* tcp_ = nullptr; + QStatusBar* statusBar; QLabel *statusInfo; @@ -156,19 +141,19 @@ private: void creat_menu(); signals: - void getRfid_signals(); - void upRfid_signals(QString rfidInfo); - void connect_socket(QString ip, int port); - void IdentifyType(); + void openCom_signals(const bool &type, const int &msec = 0); + void readTestRfid_signals(const QString &filePath); + private slots: void openComClicked(); - void readCom(); - void getQueueDataThread(); - void upRfid(QString rfidInfo); - void serialPort_error(QSerialPort::SerialPortError error); + void openComResult(const bool &success); + void closeComResult(const bool &success); + void upResultType(const bool &type); + void comeTrain(const bool &success); void on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason); void readTestInfo(); - void IdentifyTypeUpdate(); + + void statusInfoUpdate(const QString &info); void DebugSlots(const QString &info); void InfoSlots(const QString &info); diff --git a/src/serial/ComDetect.cpp b/src/serial/ComDetect.cpp index 51bf9a3..2083c93 100644 --- a/src/serial/ComDetect.cpp +++ b/src/serial/ComDetect.cpp @@ -6,90 +6,63 @@ #include "ComDetect.h" ComDetect::ComDetect() { - this->serial_ = new QSerialPort; + } ComDetect::~ComDetect() { - this->serial_->deleteLater(); + } - -QSerialPort* ComDetect::openCom(const QString &com, int baud) +bool ComDetect::openCom(QSerialPort *serial, const QString &com, int baud) { try { - this->serial_->setPortName(com); + serial->setPortName(com); if (baud == 9600) { - this->serial_->setBaudRate(QSerialPort::Baud9600); + serial->setBaudRate(QSerialPort::Baud9600); } else if (baud == 19200) { - this->serial_->setBaudRate(QSerialPort::Baud19200); + serial->setBaudRate(QSerialPort::Baud19200); } else if (baud == 115200) { - this->serial_->setBaudRate(QSerialPort::Baud115200); + serial->setBaudRate(QSerialPort::Baud115200); } else { - this->serial_->setBaudRate(QSerialPort::Baud19200); + serial->setBaudRate(QSerialPort::Baud19200); } - this->serial_->setParity(QSerialPort::NoParity);// 校验 - this->serial_->setDataBits(QSerialPort::Data8); //数据位 - this->serial_->setStopBits(QSerialPort::OneStop);//停止位,停止位默认选择1位 - this->serial_->setFlowControl(QSerialPort::NoFlowControl);// 控制流,默认选择无 - this->serial_->setReadBufferSize(1024); // 设置读取的缓冲区1024字节 + serial->setParity(QSerialPort::NoParity);// 校验 + serial->setDataBits(QSerialPort::Data8); //数据位 + serial->setStopBits(QSerialPort::OneStop);//停止位,停止位默认选择1位 + serial->setFlowControl(QSerialPort::NoFlowControl);// 控制流,默认选择无 + serial->setReadBufferSize(1024); // 设置读取的缓冲区1024字节 - if (this->serial_->open(QSerialPort::ReadWrite)) + if (serial->open(QSerialPort::ReadWrite)) { - this->serial_->clear(QSerialPort::AllDirections); - this->serial_->setDataTerminalReady(true); - return this->serial_; + serial->clear(QSerialPort::AllDirections); + serial->setDataTerminalReady(true); + return true; } } catch (const std::exception &e) { std::cout << e.what() << std::endl; - return nullptr; - } - - return nullptr; -} - -bool ComDetect::closeCom() -{ - this->serial_->clear(); - this->serial_->close(); - return true; -} - -[[deprecated("建议自行定义读取函数")]] void ComDetect::readCom() -{ - try { - QByteArray data = this->serial_->readAll(); // 读取数据 - if(!data.isEmpty()) - { -// this->queue_->push(QString(data)); - } - data.clear(); - } catch(...) { - - } -} - -bool ComDetect::writeCom(const QString &str) -{ - try - { - this->serial_->write(str.toUtf8()); - } - catch (...) - { return false; } - return true; + + return false; } + +bool ComDetect::closeCom(QSerialPort *serial) +{ + serial->clear(); + serial->close(); + + return true; +} \ No newline at end of file diff --git a/src/serial/ComDetect.h b/src/serial/ComDetect.h index 253b598..1a210f0 100644 --- a/src/serial/ComDetect.h +++ b/src/serial/ComDetect.h @@ -16,16 +16,14 @@ public: ComDetect(); ~ComDetect(); - QSerialPort* openCom(const QString &com, int baud); - bool closeCom(); - - bool writeCom(const QString &str); + bool openCom(QSerialPort *serial, const QString &com, int baud); + bool closeCom(QSerialPort *serial); private: QSerialPort *serial_{}; MQueue *queue_{}; private slots: - [[deprecated("建议自行定义读取函数")]] void readCom(); +// [[deprecated("建议自行定义读取函数")]] void readCom(); }; diff --git a/src/threads/ReadComThread.cpp b/src/threads/ReadComThread.cpp index e2ff80e..4873e9a 100644 --- a/src/threads/ReadComThread.cpp +++ b/src/threads/ReadComThread.cpp @@ -25,6 +25,9 @@ ReadComThread::ReadComThread(MQueue *queueTrainInfo, this->recvLog.setFileName(logRfidRecvName); this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append); + timer_.setSingleShot(true); + connect(&timer_, &QTimer::timeout, this, &ReadComThread::tryToReconnect); + connect(this, &ReadComThread::getRfid_signals, this, &ReadComThread::getQueueDataThread); connect(this, &ReadComThread::IdentifyType, this, &ReadComThread::IdentifyTypeUpdate); connect(this, &ReadComThread::upRfid_signals, this, &ReadComThread::upRfid); @@ -93,15 +96,18 @@ void ReadComThread::run() { while (true) { - QThread::msleep(100); - if (this->auto_reconnect_serial_) - { - QThread::msleep(10 * 1000); - if ((this->serial_ == nullptr || !this->serial_->isOpen())) - { - this->openCom(true, 0); - } - } + QThread::msleep(10 * 1000); +// if (this->auto_reconnect_serial_) +// { +// QThread::msleep(10 * 1000); +// if ((this->serial_ == nullptr || !this->serial_->isOpen())) +// { +// this->openCom(true, 0); +// } +// +// } + + } } @@ -111,10 +117,8 @@ void ReadComThread::openCom(const bool &type, const int &msec) if (type) { this->auto_reconnect_serial_ = true; - - this->serial_ = new QSerialPort; - this->serial_ = this->comDetect_.openCom(this->baseConfig_.comName, this->baseConfig_.baud); - if (this->serial_ != nullptr) + this->serial_ = new QSerialPort(this); + if (this->comDetect_->openCom(this->serial_, this->baseConfig_.comName, this->baseConfig_.baud)) { QString logs; logs.append("串口打开成功\n"); @@ -126,25 +130,26 @@ void ReadComThread::openCom(const bool &type, const int &msec) this->InfoSignals(logs); connect(this->serial_,&QSerialPort::readyRead,this,&ReadComThread::readCom); // - connect(this->serial_, &QSerialPort::errorOccurred, this, &ReadComThread::serialPort_error); - this->openComSuccess(true); - + emit this->openComSuccess(true); + this->timer_.stop(); this->initParam(); } else { + this->comDetect_->closeCom(this->serial_); this->isOpenCom = false; this->ErrorSignals("串口打开失败!"); - this->openComSuccess(false); + emit this->openComSuccess(false); + this->timer_.start(10*1000); } } else { this->auto_reconnect_serial_ = false; - if (this->comDetect_.closeCom()) + if (this->comDetect_->closeCom(this->serial_)) { this->initParam(); this->InfoSignals("串口已关闭!"); @@ -152,16 +157,23 @@ void ReadComThread::openCom(const bool &type, const int &msec) } else { - this->closeComSuccess(false); + emit this->closeComSuccess(false); } } } +void ReadComThread::tryToReconnect() +{ + if (this->auto_reconnect_serial_) + this->openCom(true); +} + void ReadComThread::readCom() { try { if (this->serial_->waitForReadyRead(10)) { QByteArray data = this->serial_->readAll(); // 读取数据 + if(!data.isEmpty()) { this->queue_.push(QString(data)); @@ -449,14 +461,9 @@ void ReadComThread::serialPort_error(QSerialPort::SerialPortError error) { //关闭串口 this->serial_->close(); - this->ErrorSignals("串口异常退出,疑似接口松动;"); - this->openComSuccess(false); - -// this->ui->openComButton->setText("打开串口"); - -// this->ui->LEDlabel->setStyleSheet("border-radius: 16px; \ " -// "background-color: red;\ " -// "border:1px solid rgba(168, 168, 168, 105);"); + this->ErrorSignals("串口异常退出,疑似接口松动;10秒后自动尝试重连..."); + emit this->openComSuccess(false); + this->timer_.start(10*1000); } } diff --git a/src/threads/ReadComThread.h b/src/threads/ReadComThread.h index 1521096..e5fbd7b 100644 --- a/src/threads/ReadComThread.h +++ b/src/threads/ReadComThread.h @@ -28,6 +28,7 @@ private: MQueue queueTmpTrainInfo_{}; // RFID临时信息队列 QSerialPort *serial_; //串口 bool auto_reconnect_serial_ = false; + QTimer timer_; ai_matrix::BaseConfig baseConfig_; ai_matrix::SServerConfig socketServerConfig_; @@ -36,7 +37,7 @@ private: QTcpSocket* tcp_ = nullptr; // Com口数据读取类 - ComDetect comDetect_; + ComDetect *comDetect_; // 打开com口标志 bool isOpenCom = false; @@ -100,6 +101,7 @@ public slots: void getQueueDataThread(); void IdentifyTypeUpdate(); void upRfid(const QString &rfidInfo); + void tryToReconnect(); void readTestInfo(const QString &filePath); };