#include #include "MainWindow.h" #include "ui_MainWindow.h" #include "TcpClient.h" #define DEBUG_HTTP 1 MainWindow::MainWindow(QWidget *parent) : QWidget(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); 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); this->statusBar->addWidget(statusVersion); layout()->addWidget(this->statusBar); this->setWindowTitle("Matrix_RFID 车号识别程序(勿关!!)"); this->configPath_ = "./config/config.ini"; if (!this->mkLogDir()) { this->logError("创建Log目录失败!"); } // 配置文件读取 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_)) { this->logError(errorMessage); } // 获取本机串口列表 this->getComList(); // 初始化界面上的串口打开参数 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();//最小化 // 设置最大展示数据行数 this->ui->textBrowser->document()->setMaximumBlockCount(1000); getStandardItemModel(); this->ui->resultTable->setModel(this->resultTableModel_); 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_.useSocketServer) { // 创建线程 QThread *threadWork = new QThread; // 任务线程 this->tcpClient = new TcpClient(this); this->tcpClient->moveToThread(threadWork); 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->start(); 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); } MainWindow::~MainWindow() { this->logInfo("-- 程序退出 --"); this->initParam(); delete ui; } void MainWindow::logDebug(const QString& message) { LogDebug << message.toStdString(); ui->textBrowser->append(QString("[Debug] [") + this->getSystemTime() + QString::fromStdString("] ") + message); } void MainWindow::logInfo(const QString& message) { LogInfo << message.toStdString(); ui->textBrowser->append(QString("[Info] [") + this->getSystemTime() + QString::fromStdString("] ") + message); } void MainWindow::logWarn(const QString& message) { LogWarn << message.toStdString(); ui->textBrowser->append(QString("[Warn] [") + this->getSystemTime() + QString::fromStdString("] ") + message); } 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; } /** * 创建日志目录 * @return bool */ bool MainWindow::mkLogDir() { if (_access("Logs", 0) == -1) { //判断是否存在日志的文件夹,没有则创建 std::string folderPath = "Logs"; if (0 != _mkdir(folderPath.c_str())) { return false; } } 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 */ QList MainWindow::getComList() { // 获取系统所有串口信息 QList availablePorts = QSerialPortInfo::availablePorts(); for (const auto & availablePort : availablePorts) { this->comList.append(availablePort.portName()); } return this->comList; } /** * 初始化 comboxBox 组件的值 */ 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->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->setMaxVisibleItems(5); ui->comBox->setView(new QListView()); ui->comBox->addItems(this->comList); if (this->baseConfig_.comName != "") { if (ui->comBox->findText(this->baseConfig_.comName) == -1) { ui->comBox->addItem(this->baseConfig_.comName); } ui->comBox->setCurrentText(this->baseConfig_.comName); } if (ui->BTBox->findText(QString::number(this->baseConfig_.baud)) == -1) { ui->BTBox->addItem(QString::number(this->baseConfig_.baud)); } ui->BTBox->setCurrentText(QString::number(this->baseConfig_.baud)); ui->truckEdit->setText(QString::number(this->baseConfig_.trackName)); this->rfidHasTrain = false; this->videoHasTrain = false; } /** * @brief:获取系统时间 * @param: * @return:空 */ QString MainWindow::getSystemTime() { return QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); } /** * 获取结果框的ItemModel * @return */ QStandardItemModel* MainWindow::getStandardItemModel() { if (this->resultTableModel_== nullptr) this->resultTableModel_ = new QStandardItemModel(); this->resultTableModel_->setColumnCount(1); this->resultTableModel_->setHeaderData(0,Qt::Horizontal, "车号"); return this->resultTableModel_; } QStandardItem* MainWindow::getStandardItem(const QString &value) { QStandardItem *resultTableItem = new QStandardItem(); resultTableItem->setTextAlignment(Qt::AlignCenter); resultTableItem->setText(value); return resultTableItem; } /***************************最小化相关****************************************/ /** * @brief:接收最小化信号 * @param: * @return:空 */ void MainWindow::changeEvent(QEvent *event) { if((event->type()==QEvent::WindowStateChange)&&isMinimized()) { this->hide(); m_pSystemTray->setIcon(QIcon("./logo.ico")); // 托盘时显示的图片 m_pSystemTray->setToolTip("Rfid车号识别-股道号:" + QString::number(this->baseConfig_.trackName)); // 鼠标在托盘图片时的提示 m_pSystemTray->showMessage("Rfid车号识别","已隐藏至托盘",QSystemTrayIcon::Information,10000); event->ignore(); //建立托盘操作的菜单 creat_action(); creat_menu(); m_pSystemTray->show(); // 显示图片图标 } } void MainWindow::closeEvent(QCloseEvent *event) { // 弹出对话框要求用户输入账号和密码 QString password = QInputDialog::getText(this, "密码验证", "请输入密码:", QLineEdit::Password); // 验证账号和密码是否正确 if (password == "matrix") { this->initParam(); this->tcp_->close(); event->accept(); // 关闭窗口 exit(0); } else { QMessageBox::warning(this, "验证失败", "密码不正确!"); event->ignore(); // 阻止关闭窗口 } } void MainWindow::creat_action() { m_pActionShow = new QAction("主界面", this); connect(m_pActionShow, &QAction::triggered, this,&MainWindow::on_ShowMainAction); // m_pActionQuit = new QAction("退出", this); // connect(m_pActionQuit, &QAction::triggered, this, &MainWindow::on_ExitAppAction); } void MainWindow::creat_menu() { m_pTrayMennu = new QMenu(this); //新增菜单项---显示主界面 m_pTrayMennu->addAction(m_pActionShow); //增加分隔符 // m_pTrayMennu->addSeparator(); // //新增菜单项---退出程序 // m_pTrayMennu->addAction(m_pActionQuit); //把QMenu赋给QSystemTrayIcon对象 m_pSystemTray->setContextMenu(m_pTrayMennu); } /** * @brief:显示 * @param: * @return:空 */ void MainWindow::on_ShowMainAction() { this->show(); this->showNormal(); this->activateWindow(); } void MainWindow::on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason) { switch(reason){ case QSystemTrayIcon::Trigger: //单击托盘图标 this->showNormal(); break; case QSystemTrayIcon::DoubleClick: //双击托盘图标 //双击后显示主程序窗口 this->showNormal(); this->activateWindow(); break; default: break; } } /********************************串口操作*************************************/ bool MainWindow::connectCom() { this->serial_ = this->comDetect_.openCom(ui->comBox->currentText(), ui->BTBox->currentText().toInt()); 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->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); return true; } else { return false; } } /** * 打开串口 */ void MainWindow::openComClicked() { if (ui->openComButton->text() == "打开串口") { this->auto_reconnect_serial_ = true; this->ui->openComButton->setText("关闭串口"); QtConcurrent::run([=](){ while (this->auto_reconnect_serial_ && !this->isOpenCom) { if (!this->connectCom()) { this->isOpenCom = false; this->comDetect_.closeCom(); this->logInfo("串口打开失败!10秒钟后将会重连..."); } else { return ; } QThread::sleep(10); } }); // this->serial_ = this->comDetect_.openCom(ui->comBox->currentText(), ui->BTBox->currentText().toInt()); // // 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->comDetect_.closeCom(); // this->logInfo("串口打开失败!10秒钟后将会重连..."); // this->ui->openComButton->setText("关闭串口"); // // QtConcurrent::run([=](){ // QThread::sleep(10); // if (this->auto_reconnect_serial_ && !this->isOpenCom) { // ui->openComButton->click(); // } // }); // } } else { this->auto_reconnect_serial_ = false; if (this->isOpenCom) { // 弹出对话框要求用户输入密码 QString password = QInputDialog::getText(this, "密码验证", "请输入密码:", QLineEdit::Password); // 验证账号和密码是否正确 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);"); } } else { QMessageBox::warning(this, "验证失败", "密码不正确!"); } } else { this->logInfo("串口已停止访问!"); this->ui->openComButton->setText("打开串口"); } } } /** * 串口异常退出的槽函数 * @param error */ void MainWindow::serialPort_error(QSerialPort::SerialPortError error) { if (error != QSerialPort::NoError) { //关闭串口 this->serial_->close(); this->ui->openComButton->setText("打开串口"); this->logError("串口异常退出,疑似接口松动"); this->ui->LEDlabel->setStyleSheet("border-radius: 16px; \ " "background-color: red;\ " "border:1px solid rgba(168, 168, 168, 105);"); QtConcurrent::run([=](){ QThread::sleep(10); if (this->auto_reconnect_serial_ && !this->isOpenCom) { this->connectCom(); } }); } } 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("读取串口数据异常!"); } } /** * @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.left(14); if (vecTrain.empty() || !vecTrain.contains(strTrainInfo)) { bool isNoCarriage = false; int carT = strTrainInfo.mid(3, 2).simplified().toInt(&isNoCarriage); if (isNoCarriage && carT >= 10) continue; // 因信号不稳定 增加一行过滤 出现文字中带有字母及数字以外的字符时,过滤 if (!strTrainInfo.contains(QRegExp("^[A-Z0-9\\s]+$"))) continue; // 因信号不稳定 增加一行过滤 出现读到的数据里 空格替代了实际字符的情况 if (strTrainInfo.mid(7, 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{ 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->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("火车离开了"); } } void MainWindow::DebugSlots(const QString &info) { this->logDebug(info); } void MainWindow::InfoSlots(const QString &info) { this->logInfo(info); } void MainWindow::WarnSlots(const QString &info) { this->logWarn(info); } void MainWindow::ErrorSlots(const QString &info) { this->logError(info); } // ============================= 测试 ==================================== void MainWindow::readTestInfo() { if (this->isOpenCom || ui->openComButton->text() == "关闭串口") { logWarn("请先关闭串口后进行测试操作!"); return; } QString filePath = QFileDialog::getOpenFileName(this, "选择一个文件", QDir::currentPath(), "(*.*)"); if(filePath.isEmpty()){ 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("---读取测试数据完毕---"); }