From: xue <2144439972@qq.com> Date: Mon, 13 Apr 2026 07:04:00 +0000 (+0800) Subject: V1.7 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=ce24e03f325d4f604b28e0c686a78c7e7f1abecf;p=mirrors%2Ffactory_tool.git V1.7 1.增加关机按钮 2.修复LCD会进入用户模式的bug 3.保存文件增加mac地址 --- diff --git a/mainwindow.cpp b/mainwindow.cpp index a6c35d3..95171cc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -30,6 +30,30 @@ #include #include #include +#include + +namespace { +QString macTagForFilename(const QString &mac) +{ + if (mac.trimmed().isEmpty()) { + return QStringLiteral("UNKNOWN"); + } + QString t = mac.trimmed().toUpper(); + t.remove(QLatin1Char(':')); + for (int i = 0; i < t.size(); ++i) { + const QChar c = t.at(i); + if (!c.isDigit() && (c < QLatin1Char('A') || c > QLatin1Char('F'))) { + t[i] = QLatin1Char('_'); + } + } + return t.isEmpty() ? QStringLiteral("UNKNOWN") : t; +} + +QString macForCsvColumn(const QString &mac) +{ + return mac.trimmed().isEmpty() ? QStringLiteral("未获取") : mac.trimmed(); +} +} // namespace MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -106,6 +130,7 @@ MainWindow::MainWindow(QWidget *parent) testLogFile = nullptr; testLogStream = nullptr; testLogFilePath = ""; + productionDeviceMac.clear(); // 初始化配置管理器 configManager.loadConfig(); // 初始化开机检测相关变量 @@ -545,11 +570,9 @@ void MainWindow::readSerialData() CheckVibratorFunc(processLine); } - // 检测wstp_print格式的BTMAC和CyweeChipInfo数据(不需要fac:开头) - if (line.contains("^^^^ BTMAC=") && line.contains("^^^^ CyweeChipInfo=")) { - // 显示到接收区 + // 检测wstp_print格式的BTMAC和/或CyweeChipInfo数据(不需要fac:开头) + if (line.contains("^^^^ BTMAC=") || line.contains("^^^^ CyweeChipInfo=")) { appendToLogFile(line); - parseWstpPrintData(line); } @@ -749,171 +772,39 @@ void MainWindow::on_ProductionTestButton_clicked() } } -// LCD测试函数 +// LCD测试:仅发送 AT^LCDTEST=1,不再发送变色/退出/关屏等其它 LCD 相关 AT void MainWindow::performLcdTest() { - // 检查LCD测试是否启用 if (!isTestItemEnabled("lcd")) { qDebug() << "LCD测试未启用,跳过"; updateTestStatus("lcd", STATUS_UNTESTED); skipToNextEnabledTest(); return; } - + if (!isProductionTestRunning || currentTestStep != TEST_LCD) { qDebug() << "LCD测试跳过 - 产测运行:" << isProductionTestRunning << "当前步骤:" << currentTestStep; return; } - // 第一次进入LCD测试时更新状态并发送进入LCD测试模式指令 - if (currentLcdColor == 1) { - ui->recvTextEdit->append("========== 开始LCD测试 =========="); - updateTestStatus("lcd", STATUS_TESTING); - - // 发送进入LCD测试模式指令 - serial->write("AT^LCDTEST=1\r\n"); - qDebug() << "发送进入LCD测试模式指令: AT^LCDTEST=1"; - ui->statusbar->showMessage("进入LCD测试模式,1秒后开始颜色测试...", 1000); - - // 延迟1秒后开始颜色测试,确保设备完全进入LCD测试模式 - QTimer::singleShot(1000, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_LCD) { - qDebug() << "LCD测试模式初始化完成,开始颜色测试"; - performLcdColorTest(); - } - }); - return; - } - - // 直接执行颜色测试 - performLcdColorTest(); -} + ui->recvTextEdit->append("========== 开始LCD测试 =========="); + updateTestStatus("lcd", STATUS_TESTING); -// LCD颜色测试函数 -void MainWindow::performLcdColorTest() -{ - if (!isProductionTestRunning || currentTestStep != TEST_LCD) { - qDebug() << "LCD颜色测试跳过 - 产测运行:" << isProductionTestRunning << "当前步骤:" << currentTestStep; - return; - } - - qDebug() << "LCD测试 - 测试步骤:" << currentLcdColor << "定时器状态:" << lcdTestTimer->isActive(); - - // 在第一个颜色(红色)开始时就显示确认弹窗 - if (currentLcdColor == 1 && !lcdTestPopupShown) { - qDebug() << "LCD测试开始,显示确认弹窗"; - // 延迟一点显示弹窗,让红色先显示 - QTimer::singleShot(500, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_LCD && !lcdTestPopupShown) { - showLcdTestConfirmDialog(); - } - }); - } - - QString colorName; - int colorCommand; - switch (currentLcdColor) { - case 1: - colorName = "红色"; - colorCommand = 6; // AT^LCDTEST=6 红色 - break; - case 2: - colorName = "绿色"; - colorCommand = 3; // AT^LCDTEST=3 绿色 - break; - case 3: - colorName = "蓝色"; - colorCommand = 4; // AT^LCDTEST=4 蓝色 - break; - default: - colorName = "未知"; - colorCommand = 6; - break; - } - - ui->statusbar->showMessage("LCD测试中 - " + colorName + " (1秒)", 1000); - - // 发送LCD测试指令,使用正确的颜色映射 - QString command = QString("AT^LCDTEST=%1\r\n").arg(colorCommand); - serial->write(command.toUtf8()); - qDebug() << "发送LCD指令:" << command.trimmed() << "(" << colorName << ")"; - - // 设置1秒定时器 - lcdTestTimer->start(1000); + serial->write("AT^LCDTEST=1\r\n"); + qDebug() << "LCD测试仅发送: AT^LCDTEST=1"; + ui->statusbar->showMessage("已发送 AT^LCDTEST=1,请观察屏幕", 3000); + + QTimer::singleShot(800, this, [this]() { + if (isProductionTestRunning && currentTestStep == TEST_LCD && !lcdTestPopupShown) { + showLcdTestConfirmDialog(); + } + }); } -// LCD测试定时器槽函数 +// LCD 颜色轮询已移除;定时器保留连接,避免误触发时无操作 void MainWindow::onLcdTestTimer() { lcdTestTimer->stop(); - qDebug() << "LCD定时器触发,当前颜色:" << currentLcdColor; - - if (!isProductionTestRunning) { - qDebug() << "产测未运行,退出定时器"; - return; - } - - currentLcdColor++; - qDebug() << "切换到下一个颜色:" << currentLcdColor; - - if (currentLcdColor <= 3) { - // 继续下一个颜色测试 - qDebug() << "继续下一个颜色测试"; - performLcdColorTest(); - } else { - // LCD测试完成,发送退出LCD测试指令 - qDebug() << "LCD测试完成,退出LCD测试界面"; - ui->statusbar->showMessage("LCD测试完成,退出测试界面", 1000); - - // 发送退出LCD测试指令 - serial->write("AT^LCDTEST=2\r\n"); - qDebug() << "发送LCD退出指令: AT^LCDTEST=2"; - - // 如果LCD测试被选中且LCD是开启状态,才需要关闭LCD - if (isTestItemEnabled("lcd") && lcdBacklightOn) { - // 发送关闭LCD指令 - QTimer::singleShot(100, this, [this]() { - if (isProductionTestRunning && serial && serial->isOpen()) { - serial->write("AT^LCDOFF\r\n"); - qDebug() << "发送指令: AT^LCDOFF (关闭LCD)"; - ui->recvTextEdit->append(">>> 发送指令: AT^LCDOFF (关闭LCD)"); - - // LCD关闭后延迟1秒,然后延迟2秒再继续下一个测试 - QTimer::singleShot(1000, this, [this]() { - // LCD颜色测试完成,检查用户是否已确认 - if (!isWaitingForUserConfirm) { - // 用户已确认,延迟2秒后继续下一个测试 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning) { - qDebug() << "用户已确认LCD结果,推进到下一个测试"; - skipToNextEnabledTest(); - } - }); - } else { - // 用户还未确认,等待用户确认后再继续 - qDebug() << "LCD颜色测试完成,等待用户确认结果"; - ui->statusbar->showMessage("LCD测试完成,等待用户确认结果", 3000); - } - }); - } - }); - } else { - // LCD测试未启用或LCD已关闭,直接继续 - if (!isWaitingForUserConfirm) { - // 用户已确认,延迟2秒后继续下一个测试 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning) { - qDebug() << "用户已确认LCD结果,推进到下一个测试"; - skipToNextEnabledTest(); - } - }); - } else { - // 用户还未确认,等待用户确认后再继续 - qDebug() << "LCD颜色测试完成,等待用户确认结果"; - ui->statusbar->showMessage("LCD测试完成,等待用户确认结果", 3000); - } - } - } } // 马达测试函数 @@ -1104,29 +995,10 @@ void MainWindow::checkFactoryModeResult(const QString& data) } } -// 检查LCD测试结果 +// 检查LCD测试结果(已改为仅发 AT^LCDTEST=1 + 延时弹窗确认,不再依赖串口触发) void MainWindow::checkLcdTestResult(const QString& data) { - // 检测LCD测试回复信息,并且只在LCD测试阶段且未显示过弹窗时弹出 - // 修改:在最后一个颜色(蓝色)显示时才弹窗,让用户观察完整过程 - if (data.contains("LCD test") && currentTestStep == TEST_LCD && - !lcdTestPopupShown && isProductionTestRunning && currentLcdColor >= 3) { - - qDebug() << "检测到LCD测试回复:" << data.trimmed(); - qDebug() << "准备显示LCD测试确认弹窗"; - - // 标记弹窗已显示,避免重复弹出 - lcdTestPopupShown = true; - isWaitingForUserConfirm = true; - - // 注意:不暂停LCD定时器,让颜色切换继续进行 - // LCD颜色切换应该独立于用户确认过程 - qDebug() << "显示LCD确认弹窗,但颜色切换继续进行"; - - // LCD测试回复已检测到,弹窗处理由performLcdTest中的定时器处理 - - // 不需要在这里处理弹窗,由performLcdTest中的定时器处理 - } + Q_UNUSED(data); } // 显示LCD测试确认弹窗 @@ -1146,8 +1018,8 @@ void MainWindow::showLcdTestConfirmDialog() // 弹出确认对话框让测试人员确认LCD显示是否正常 QMessageBox msgBox(this); msgBox.setWindowTitle("LCD测试确认"); - msgBox.setText("LCD测试正在进行,请观察LCD是否正常显示红、绿、蓝、白色切换"); - msgBox.setInformativeText("观察完成后请选择LCD显示结果:"); + msgBox.setText("已发送 AT^LCDTEST=1,请观察 LCD 显示是否正常"); + msgBox.setInformativeText("观察完成后请选择结果:"); msgBox.setIcon(QMessageBox::Question); // 设置弹窗尺寸更大 @@ -1209,138 +1081,30 @@ void MainWindow::showLcdTestConfirmDialog() // 根据用户选择处理结果 if (msgBox.clickedButton() == successButton) { - // 测试人员确认LCD显示正常 qDebug() << "测试人员确认:LCD显示正常"; ui->statusbar->showMessage("LCD显示正常", 2000); - updateTestStatus("lcd", STATUS_SUCCESS); - - // 发送停止LCD测试指令 - serial->write("AT^LCDTEST=2\r\n"); - qDebug() << "LCD测试通过,发送停止LCD测试指令: AT^LCDTEST=2"; - - // 如果LCD测试被选中且LCD是开启状态,才需要关闭LCD - if (isTestItemEnabled("lcd") && lcdBacklightOn) { - // 发送关闭LCD指令 - QTimer::singleShot(100, this, [this]() { - if (isProductionTestRunning && serial && serial->isOpen()) { - serial->write("AT^LCDOFF\r\n"); - qDebug() << "发送指令: AT^LCDOFF (关闭LCD)"; - ui->recvTextEdit->append(">>> 发送指令: AT^LCDOFF (关闭LCD)"); - - // LCD关闭后延迟1秒,然后延迟2秒再继续下一个测试 - QTimer::singleShot(1000, this, [this]() { - // 停止LCD定时器,防止继续切换颜色和重复调用马达测试 - if (lcdTestTimer->isActive()) { - lcdTestTimer->stop(); - qDebug() << "停止LCD定时器,防止继续切换颜色和重复调用马达测试"; - } - - // 推进到下一个启用的测试 - if (isProductionTestRunning) { - qDebug() << "LCD测试通过确认,延迟2秒后推进到下一个测试"; - qDebug() << "当前产测状态:" << isProductionTestRunning << "当前测试步骤:" << currentTestStep; - - // 延迟2秒确保LCD完全关闭,然后推进到下一个测试 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning) { - skipToNextEnabledTest(); - } - }); - } else { - qDebug() << "产测未运行,无法继续测试"; - } - }); - } - }); - } else { - // LCD测试未启用或LCD已关闭,直接继续 - // 停止LCD定时器,防止继续切换颜色和重复调用马达测试 + updateTestStatus("lcd", STATUS_SUCCESS); if (lcdTestTimer->isActive()) { lcdTestTimer->stop(); - qDebug() << "停止LCD定时器,防止继续切换颜色和重复调用马达测试"; - } - - // 推进到下一个启用的测试 - if (isProductionTestRunning) { - qDebug() << "LCD测试通过确认,延迟2秒后推进到下一个测试"; - qDebug() << "当前产测状态:" << isProductionTestRunning << "当前测试步骤:" << currentTestStep; - - // 延迟2秒确保LCD完全关闭,然后推进到下一个测试 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning) { - skipToNextEnabledTest(); - } - }); - } else { - qDebug() << "产测未运行,无法继续测试"; } - } - + QTimer::singleShot(2000, this, [this]() { + if (isProductionTestRunning) { + skipToNextEnabledTest(); + } + }); } else if (msgBox.clickedButton() == failButton) { - // 测试人员确认LCD显示异常 qDebug() << "测试人员确认:LCD显示异常"; ui->statusbar->showMessage("LCD显示异常!", 2000); - updateTestStatus("lcd", STATUS_FAILED); - - // 发送停止LCD测试指令 - serial->write("AT^LCDTEST=2\r\n"); - qDebug() << "LCD测试失败,发送停止LCD测试指令: AT^LCDTEST=2"; - - // 如果LCD测试被选中且LCD是开启状态,才需要关闭LCD - if (isTestItemEnabled("lcd") && lcdBacklightOn) { - // 发送关闭LCD指令 - QTimer::singleShot(100, this, [this]() { - if (isProductionTestRunning && serial && serial->isOpen()) { - serial->write("AT^LCDOFF\r\n"); - qDebug() << "发送指令: AT^LCDOFF (关闭LCD)"; - ui->recvTextEdit->append(">>> 发送指令: AT^LCDOFF (关闭LCD)"); - - // LCD关闭后延迟1秒,然后延迟2秒再继续下一个测试 - QTimer::singleShot(1000, this, [this]() { - // 停止LCD定时器,防止重复调用马达测试 - if (lcdTestTimer->isActive()) { - lcdTestTimer->stop(); - qDebug() << "停止LCD定时器,防止重复调用马达测试"; - } - - // 即使失败也继续下一个测试 - if (isProductionTestRunning) { - qDebug() << "LCD测试失败确认,延迟2秒后继续下一个测试"; - qDebug() << "当前产测状态:" << isProductionTestRunning << "当前测试步骤:" << currentTestStep; - - // 延迟2秒确保LCD完全关闭,然后继续下一个测试 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning) { - skipToNextEnabledTest(); - } - }); - } - }); - } - }); - } else { - // LCD测试未启用或LCD已关闭,直接继续 - // 停止LCD定时器,防止重复调用马达测试 + updateTestStatus("lcd", STATUS_FAILED); if (lcdTestTimer->isActive()) { lcdTestTimer->stop(); - qDebug() << "停止LCD定时器,防止重复调用马达测试"; } - - // 即使失败也继续下一个测试 - if (isProductionTestRunning) { - qDebug() << "LCD测试失败确认,延迟2秒后继续下一个测试"; - qDebug() << "当前产测状态:" << isProductionTestRunning << "当前测试步骤:" << currentTestStep; - - // 延迟2秒确保LCD完全关闭,然后继续下一个测试 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning) { - skipToNextEnabledTest(); - } - }); - } - } - - } else if (msgBox.clickedButton() == retestButton) { + QTimer::singleShot(2000, this, [this]() { + if (isProductionTestRunning) { + skipToNextEnabledTest(); + } + }); + } else if (msgBox.clickedButton() == retestButton) { // 重新测试LCD qDebug() << "用户选择重新测试LCD"; ui->statusbar->showMessage("重新开始LCD测试", 2000); @@ -1348,7 +1112,7 @@ void MainWindow::showLcdTestConfirmDialog() // 重置LCD测试状态 lcdTestPopupShown = false; isWaitingForUserConfirm = false; - currentLcdColor = 1; // 设置为1,从红色开始重新测试 + currentLcdColor = 1; // 重新开始LCD测试 // 检查LCD测试是否启用 @@ -1363,8 +1127,7 @@ void MainWindow::showLcdTestConfirmDialog() return; // 直接返回,不继续后续流程 } - // 用户确认完成,马达测试已在上面的按钮处理中启动 - qDebug() << "用户确认完成,马达测试已启动"; + qDebug() << "LCD测试确认流程结束"; } // 显示马达测试确认弹窗 @@ -2413,17 +2176,20 @@ QString MainWindow::saveTestRecord() dir.mkpath(saveDir); } - QString csvFileName = "产测记录.csv"; - QString csvFilePath = saveDir + "/" + csvFileName; + const QString macTag = macTagForFilename(productionDeviceMac); + const QString timeTag = endTime.toString("yyyyMMdd_hhmmss_zzz"); - bool isNewFile = !QFile::exists(csvFilePath); + const QString csvFileName = QStringLiteral("产测记录.csv"); + const QString csvFilePath = saveDir + "/" + csvFileName; const QString header = - "开始时间,结束时间,测试耗时,软件版本,LCD测试,触控测试,亮度测试,马达测试,按键测试,功耗测试,录音测试,电池测试,G-sensor测试,漏光测试,蓝牙测试,SE芯片测试,GPS测试,整体结果\n"; + "开始时间,结束时间,设备MAC,测试耗时,软件版本,LCD测试,触控测试,亮度测试,马达测试,按键测试,功耗测试,录音测试,电池测试,G-sensor测试,漏光测试,蓝牙测试,SE芯片测试,GPS测试,整体结果\n"; - QString newDataLine = QString("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15,%16,%17,%18\n") + const QString macCol = macForCsvColumn(productionDeviceMac); + QString newDataLine = QString("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15,%16,%17,%18,%19\n") .arg(startTimeStr) .arg(endTimeStr) + .arg(macCol) .arg(durationStr) .arg(ver.isEmpty() ? "未获取" : ver) .arg(lcdResult) @@ -2441,8 +2207,10 @@ QString MainWindow::saveTestRecord() .arg(gpsResult) .arg(overallResult); + const bool needHeader = !QFile::exists(csvFilePath) || QFileInfo(csvFilePath).size() == 0; + QFile csvFile(csvFilePath); - if (!csvFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { + if (!csvFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { QMessageBox::warning(this, "保存失败", QString("无法写入测试记录文件:\n%1\n错误:%2") .arg(csvFilePath) @@ -2450,13 +2218,13 @@ QString MainWindow::saveTestRecord() return QString(); } - if (isNewFile) { + if (needHeader) { csvFile.write(header.toLocal8Bit()); } csvFile.write(newDataLine.toLocal8Bit()); csvFile.close(); - qDebug() << "测试记录已追加保存到:" << csvFilePath; + qDebug() << "测试记录已追加到:" << csvFilePath; ui->statusbar->showMessage(QString("测试记录已保存: %1").arg(csvFileName), 3000); @@ -2476,7 +2244,12 @@ QString MainWindow::saveTestRecord() testLogStream->flush(); } - closeTestLogFile(); + const QString logsDirForRename = appPath + "/产测记录/logs"; + QString finalLogPath = logsDirForRename + "/" + timeTag + "_" + macTag + ".log"; + for (int dup = 1; QFile::exists(finalLogPath) && dup < 100; ++dup) { + finalLogPath = logsDirForRename + "/" + timeTag + "_" + macTag + "_" + QString::number(dup) + ".log"; + } + closeTestLogFile(finalLogPath); // 保存UI日志到独立文件(如果有效) saveRecvTextEditToLog(); @@ -2493,55 +2266,34 @@ QString MainWindow::saveTestRecord() void MainWindow::parseWstpPrintData(const QString& data) { qDebug() << "检测到wstp_print格式数据:" << data.trimmed(); - - // 解析BTMAC地址 - // 格式:^^^^ BTMAC=XX:XX:XX:XX:XX:XX ^^^^ - QRegExp btmacPattern("\\^\\^\\^\\^ BTMAC=([0-9A-Fa-f:]{17}) \\^\\^\\^\\^"); - if (btmacPattern.indexIn(data) != -1) { - QString btmac = btmacPattern.cap(1); - qDebug() << "解析到BTMAC地址:" << btmac; - - // 这里可以将BTMAC地址填充到相应的文本框 - // 如果有专门的BTMAC文本框,可以这样设置: - // ui->btmacLineEdit->setText(btmac); - - // 暂时显示在状态栏 - ui->statusbar->showMessage(QString("检测到蓝牙MAC地址: %1").arg(btmac), 3000); - } - - // 解析CyweeChipInfo - // 格式:^^^^ CyweeChipInfo=XXXXXX ^^^^ - QRegExp chipinfoPattern("\\^\\^\\^\\^ CyweeChipInfo=([^\\s\\^]+)"); - if (chipinfoPattern.indexIn(data) != -1) { - QString chipinfo = chipinfoPattern.cap(1); - qDebug() << "解析到CyweeChipInfo:" << chipinfo; - - // 这里可以将芯片信息填充到相应的文本框 - // 如果有专门的芯片信息文本框,可以这样设置: - // ui->chipinfoLineEdit->setText(chipinfo); - - // 暂时显示在状态栏 - ui->statusbar->showMessage(QString("检测到芯片信息: %1").arg(chipinfo), 3000); - } - - // 完整的数据格式示例: - // wstp_print("^^^^ BTMAC=%s ^^^^ CyweeChipInfo=%s\n",btaddr_str,chipinfo); - // 实际输出可能是:^^^^ BTMAC=AA:BB:CC:DD:EE:FF ^^^^ CyweeChipInfo=MSA310 - - // 如果需要同时解析两个值的完整格式 + + QString btmac; + bool fullMatched = false; QRegExp fullPattern("\\^\\^\\^\\^ BTMAC=([0-9A-Fa-f:]{17}) \\^\\^\\^\\^ CyweeChipInfo=([^\\s\\^\\n]+)"); if (fullPattern.indexIn(data) != -1) { - QString btmac = fullPattern.cap(1); - QString chipinfo = fullPattern.cap(2); - + fullMatched = true; + btmac = fullPattern.cap(1); + const QString chipinfo = fullPattern.cap(2); qDebug() << "完整解析 - BTMAC:" << btmac << ", CyweeChipInfo:" << chipinfo; - - // 可以在这里将信息填充到对应的UI控件 - // 例如: - // ui->btmacLineEdit->setText(btmac); - // ui->chipinfoLineEdit->setText(chipinfo); - ui->statusbar->showMessage(QString("设备信息 - MAC: %1, 芯片: %2").arg(btmac, chipinfo), 5000); + } else { + QRegExp btmacPattern("\\^\\^\\^\\^ BTMAC=([0-9A-Fa-f:]{17}) \\^\\^\\^\\^"); + if (btmacPattern.indexIn(data) != -1) { + btmac = btmacPattern.cap(1); + qDebug() << "解析到BTMAC地址:" << btmac; + ui->statusbar->showMessage(QString("检测到蓝牙MAC地址: %1").arg(btmac), 3000); + } + } + + if (!btmac.isEmpty()) { + productionDeviceMac = btmac.toUpper(); + } + + QRegExp chipinfoPattern("\\^\\^\\^\\^ CyweeChipInfo=([^\\s\\^]+)"); + if (chipinfoPattern.indexIn(data) != -1 && !fullMatched) { + const QString chipinfo = chipinfoPattern.cap(1); + qDebug() << "解析到CyweeChipInfo:" << chipinfo; + ui->statusbar->showMessage(QString("检测到芯片信息: %1").arg(chipinfo), 3000); } } @@ -2564,7 +2316,7 @@ void MainWindow::on_openRecordsFolderButton_clicked() if (success) { qDebug() << "成功打开文件夹:" << saveDir; ui->statusbar->showMessage("已打开产测记录文件夹", 2000); - } else { + } else { qDebug() << "打开文件夹失败:" << saveDir; QMessageBox::warning(this, "打开失败", QString("无法打开文件夹:\n%1\n请检查路径是否存在或权限是否足够").arg(saveDir)); @@ -2617,7 +2369,8 @@ void MainWindow::on_openButton_2_clicked() // 在开始新测试前,尽量保存当前UI日志(如果有内容) saveRecvTextEditToLog(); - + productionDeviceMac.clear(); + // 创建测试日志文件 createTestLogFile(); @@ -2662,8 +2415,8 @@ void MainWindow::on_openButton_2_clicked() ui->statusbar->showMessage("开始产测流程...", 2000); qDebug() << "=== 开始产测流程 ==="; - qDebug() << "流程: 产测开启(AT^FACTORY=1) → 设备重启 → … → 全部完成后弹窗确认 → AT^POWEROFF(关机)"; - qDebug() << "LCD指令映射: 进入=AT^LCDTEST=1, 红色=AT^LCDTEST=6, 绿色=AT^LCDTEST=3, 蓝色=AT^LCDTEST=4, 退出=AT^LCDTEST=2"; + qDebug() << "流程: 产测开启(AT^FACTORY=1) → 设备重启 → … → 全部完成后弹窗确认 → AT^RESTORE(恢复出厂) → AT^POWEROFF(关机)"; + qDebug() << "LCD测试: 仅发送 AT^LCDTEST=1"; // 发送产测开启指令,等待工厂模式确认 qDebug() << "Step 1: 发送产测开启指令"; @@ -4332,8 +4085,8 @@ void MainWindow::onTestTimeout() // 先发送停止指令,然后重新开始测试 qDebug() << "重试前发送停止指令"; serial->write("AT^VIBRATORTIMER=0\r\n"); // 停止马达 - serial->write("AT^LCDTEST=2\r\n"); // 退出LCD测试 - + // LCD 产测仅使用 AT^LCDTEST=1,不再发 LCDTEST=2 等 + // 延迟500ms后重新开始测试 QTimer::singleShot(500, this, [this, testDescription]() { qDebug() << "停止指令已发送,开始重试" << testDescription; @@ -4795,38 +4548,18 @@ void MainWindow::on_getVersionInfoButton_clicked() startVersionInfoFetch(); } -// 压力测试按钮点击事件 +// 原「压力测试」按钮:发送关机指令 AT^POWEROFF void MainWindow::on_pushButtonStressTest_clicked() { - // 检查串口是否已打开 - if (!serial->isOpen()) { - QMessageBox::warning(this, "警告", "请先打开串口连接"); - return; - } - - // 从配置管理器获取压力测试指令 - QString stressTestCmd = configManager.getStressTestCommand(); - - if (stressTestCmd.isEmpty()) { - QMessageBox::warning(this, "警告", "压力测试指令未配置"); - qDebug() << "压力测试指令为空,无法执行"; + if (!serial || !serial->isOpen()) { + QMessageBox::warning(this, "关机", "请先打开串口后再发送关机指令"); return; } - - // 确保指令以\r\n结尾 - if (!stressTestCmd.endsWith("\r\n")) { - stressTestCmd += "\r\n"; - } - - // 发送压力测试指令 - serial->write(stressTestCmd.toUtf8()); - qDebug() << "发送压力测试指令:" << stressTestCmd.trimmed(); - - // 在日志中记录 - appendToLogFile(QString("=== 发送压力测试指令: %1 ===\n").arg(stressTestCmd.trimmed())); - - // 状态栏提示 - ui->statusbar->showMessage("已发送压力测试指令", 3000); + ui->recvTextEdit->append(">>> 发送指令: AT^POWEROFF (手动关机)"); + serial->write("AT^POWEROFF\r\n"); + qDebug() << "手动发送关机指令: AT^POWEROFF"; + ui->statusbar->showMessage("已发送关机指令 AT^POWEROFF", 3000); + appendToLogFile("=== 发送关机指令: AT^POWEROFF ===\n"); } // 保存测试参数到settings.json @@ -5178,11 +4911,11 @@ void MainWindow::saveRecvTextEditToLog() dir.mkpath(logsDir); } - // 生成日志文件名 QDateTime now = QDateTime::currentDateTime(); + const QString macTag = macTagForFilename(productionDeviceMac); QString fileName = QString("%1_%2_UI日志.log") - .arg(now.toString("yyyyMMdd")) - .arg(now.toString("hhmmss")); + .arg(now.toString("yyyyMMdd_hhmmss")) + .arg(macTag); QString filePath = logsDir + "/" + fileName; @@ -5207,8 +4940,8 @@ void MainWindow::saveRecvTextEditToLog() if (!fullLogContent.trimmed().isEmpty()) { // 生成完整日志文件名(加full后缀) QString fullFileName = QString("%1_%2_UI日志full.log") - .arg(now.toString("yyyyMMdd")) - .arg(now.toString("hhmmss")); + .arg(now.toString("yyyyMMdd_hhmmss")) + .arg(macTag); QString fullFilePath = logsDir + "/" + fullFileName; @@ -5248,16 +4981,14 @@ void MainWindow::createTestLogFile() dir.mkpath(logsDir); } - // 生成文件名:yyyymmdd_hhmmss.log - QString fileName = QString("%1_%2.log") - .arg(now.toString("yyyyMMdd")) - .arg(now.toString("hhmmss")); - + // 临时文件名,结束保存时再重命名为 时间_MAC.log + QString fileName = QString("%1_pending.log").arg(now.toString("yyyyMMdd_hhmmss")); + testLogFilePath = logsDir + "/" + fileName; - + // 创建并打开日志文件 testLogFile = new QFile(testLogFilePath); - if (!testLogFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { + if (!testLogFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { qDebug() << "无法创建日志文件:" << testLogFilePath << "错误:" << testLogFile->errorString(); delete testLogFile; testLogFile = nullptr; @@ -5293,14 +5024,16 @@ void MainWindow::appendToLogFile(const QString& text) } } -// 关闭测试日志文件 -void MainWindow::closeTestLogFile() +// 关闭测试日志文件;renameToPath 非空且原路径存在时,关闭后重命名为最终路径 +void MainWindow::closeTestLogFile(const QString &renameToPath) { + const QString oldPath = testLogFilePath; + if (testLogStream) { delete testLogStream; testLogStream = nullptr; } - + if (testLogFile) { if (testLogFile->isOpen()) { testLogFile->close(); @@ -5308,8 +5041,21 @@ void MainWindow::closeTestLogFile() delete testLogFile; testLogFile = nullptr; } - - testLogFilePath = ""; + + testLogFilePath.clear(); + + if (!renameToPath.isEmpty() && !oldPath.isEmpty() && QFile::exists(oldPath)) { + QFileInfo fi(renameToPath); + QDir().mkpath(fi.absolutePath()); + if (QFile::exists(renameToPath)) { + QFile::remove(renameToPath); + } + if (!QFile::rename(oldPath, renameToPath)) { + qDebug() << "测试日志重命名失败:" << oldPath << "->" << renameToPath; + } else { + qDebug() << "测试日志已重命名为:" << renameToPath; + } + } } // 使用设备信息重命名日志文件 diff --git a/mainwindow.h b/mainwindow.h index 91e1042..3215a5a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -55,8 +55,7 @@ private slots: // 产测相关槽函数 void on_ProductionTestButton_clicked(); // 开始产测 - void performLcdTest(); // LCD测试 - void performLcdColorTest(); // LCD颜色测试 + void performLcdTest(); // LCD测试(仅 AT^LCDTEST=1) void performMotorTest(); // 马达测试 void performMotorTestContinue(); // 继续马达测试(LCD关闭后调用) void onLcdTestTimer(); // LCD测试定时器 @@ -107,7 +106,7 @@ private slots: // 日志记录相关函数 void createTestLogFile(); // 创建测试日志文件 void appendToLogFile(const QString& text); // 追加内容到日志文件(同时显示到recvTextEdit) - void closeTestLogFile(); // 关闭测试日志文件 + void closeTestLogFile(const QString &renameToPath = QString()); // 关闭测试日志文件;非空则关闭后重命名 void renameLogFileWithDeviceInfo(); // 使用设备信息重命名日志文件 void on_openButton_4_clicked(); @@ -123,7 +122,7 @@ private slots: // 版本信息获取按钮 void on_getVersionInfoButton_clicked(); - // 压力测试按钮 + // 关机按钮(界面原「压力测试」槽名未改,避免破坏 uic 自动连接) void on_pushButtonStressTest_clicked(); private: @@ -181,6 +180,7 @@ private: QFile *testLogFile; // 测试日志文件对象 QTextStream *testLogStream; // 测试日志文件流 QString testLogFilePath; // 测试日志文件路径 + QString productionDeviceMac; // 设备蓝牙 MAC(wstp_print 解析),用于 CSV/文件名 // 配置管理 ConfigManager configManager; // 配置管理器(不使用指针,直接作为成员) diff --git a/mainwindow.ui b/mainwindow.ui index 4d0cd0d..2381a98 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -75,17 +75,17 @@ QPushButton { -background-color: #ff0000; +background-color: #C62828; color: white; border-radius: 4px; font-weight: bold; } QPushButton:hover { -background-color: #F57C00; +background-color: #B71C1C; } - 压力测试 + 关机