#include <QBrush>
#include <QGraphicsView>
#include <QResizeEvent>
+#include <QFileInfo>
+
+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)
testLogFile = nullptr;
testLogStream = nullptr;
testLogFilePath = "";
+ productionDeviceMac.clear();
// 初始化配置管理器
configManager.loadConfig();
// 初始化开机检测相关变量
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);
}
}
}
-// 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);
- }
- }
- }
}
// 马达测试函数
}
}
-// 检查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测试确认弹窗
// 弹出确认对话框让测试人员确认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);
// 设置弹窗尺寸更大
// 根据用户选择处理结果
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);
// 重置LCD测试状态
lcdTestPopupShown = false;
isWaitingForUserConfirm = false;
- currentLcdColor = 1; // 设置为1,从红色开始重新测试
+ currentLcdColor = 1;
// 重新开始LCD测试
// 检查LCD测试是否启用
return; // 直接返回,不继续后续流程
}
- // 用户确认完成,马达测试已在上面的按钮处理中启动
- qDebug() << "用户确认完成,马达测试已启动";
+ qDebug() << "LCD测试确认流程结束";
}
// 显示马达测试确认弹窗
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)
.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)
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);
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();
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);
}
}
if (success) {
qDebug() << "成功打开文件夹:" << saveDir;
ui->statusbar->showMessage("已打开产测记录文件夹", 2000);
- } else {
+ } else {
qDebug() << "打开文件夹失败:" << saveDir;
QMessageBox::warning(this, "打开失败",
QString("无法打开文件夹:\n%1\n请检查路径是否存在或权限是否足够").arg(saveDir));
// 在开始新测试前,尽量保存当前UI日志(如果有内容)
saveRecvTextEditToLog();
-
+ productionDeviceMac.clear();
+
// 创建测试日志文件
createTestLogFile();
ui->statusbar->showMessage("开始产测流程...", 2000);
qDebug() << "=== 开始产测流程 ===";
- qDebug() << "流程: 产测开启(AT^FACTORY=1) → 设备重启 → … → 全部完成后弹窗确认 → AT^POWEROFF(关机)";
- qDebug() << "LCDæ\8c\87令æ\98 å°\84: è¿\9bå\85¥=AT^LCDTEST=1, 红è\89²=AT^LCDTEST=6, 绿è\89²=AT^LCDTEST=3, è\93\9dè\89²=AT^LCDTEST=4, é\80\80å\87º=AT^LCDTEST=2";
+ qDebug() << "流程: 产测开启(AT^FACTORY=1) → 设备重启 → … → 全部完成后弹窗确认 → AT^RESTORE(恢复出厂) → AT^POWEROFF(关机)";
+ qDebug() << "LCDæµ\8bè¯\95: ä»\85å\8f\91é\80\81 AT^LCDTEST=1";
// 发送产测开启指令,等待工厂模式确认
qDebug() << "Step 1: 发送产测开启指令";
// 先发送停止指令,然后重新开始测试
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;
startVersionInfoFetch();
}
-// å\8e\8bå\8a\9bæµ\8bè¯\95æ\8c\89é\92®ç\82¹å\87»äº\8bä»¶
+// å\8e\9fã\80\8cå\8e\8bå\8a\9bæµ\8bè¯\95ã\80\8dæ\8c\89é\92®ï¼\9aå\8f\91é\80\81å\85³æ\9cºæ\8c\87令 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
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;
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;
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;
}
}
-// 关闭测试日志文件
-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();
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;
+ }
+ }
}
// 使用设备信息重命名日志文件