Files
QT_wuhan_YT/pages/selfcheck.cpp
T
2026-10-16 09:06:03 +08:00

260 lines
9.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "selfcheck.h"
#include "titlebar.h"
#include "ledindicator.h"
#include "car.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QProgressBar>
#include <QTimer>
#include "confirmdialog.h"
#include "global.h"
SelfCheckPage::SelfCheckPage(AppContext* ctx, QWidget* parent)
: BasePage(ctx, parent)
{
QVBoxLayout* root = new QVBoxLayout(this);
root->setContentsMargins(0, 0, 0, 0);
root->setSpacing(0);
m_titleBar = new TitleBar(ctx, this);
m_titleBar->setTitle("系统启动及自检");
root->addWidget(m_titleBar);
// 主区
QHBoxLayout* main = new QHBoxLayout();
main->setContentsMargins(20, 30, 20, 30);
main->setSpacing(40);
// 两侧按钮统一样式:左右两列 5 个按钮统一高度 sideBtnH,字号在此统一调整
const int sideBtnH = 120;
const QString sideBtnStyle = "font-size:60px;";
auto makeSideBtn = [&](const QString& text, const QString& variant, QWidget* parent) {
QPushButton* b = button(text, variant, parent);
b->setFixedHeight(sideBtnH); // 左右两列共用同一高度值
b->setStyleSheet(sideBtnStyle);
return b;
};
// 左按钮列(高度统一为 sideBtnH,整列垂直居中)
QWidget* left = new QWidget(this);
QVBoxLayout* leftLay = new QVBoxLayout(left);
leftLay->setContentsMargins(20, 220, 20, 220);
leftLay->setSpacing(220);
m_faultQuery = makeSideBtn("故障查询", "", left);
connect(m_faultQuery, &QPushButton::clicked, this, [this]() { emit navigate(PageFault); });
m_ignore = makeSideBtn("忽略故障", "", left);
connect(m_ignore, &QPushButton::clicked, this, &SelfCheckPage::onIgnoreFault);
m_ignore->setEnabled(false);
leftLay->addStretch(1);
leftLay->addWidget(m_faultQuery);
leftLay->addWidget(m_ignore);
leftLay->addStretch(1);
left->setFixedWidth(300);
main->addWidget(left);
// 中央区
QWidget* center = new QWidget(this);
QVBoxLayout* centerLay = new QVBoxLayout(center);
centerLay->setContentsMargins(0, 0, 0, 0);
centerLay->setSpacing(0);
centerLay->addStretch(1); // 上方留白
m_status = label("自检中", 60, C::WARNING, true, center);
m_status->setAlignment(Qt::AlignCenter);
centerLay->addWidget(m_status);
centerLay->addSpacing(16);
// 14 个自检项,两列各 7 行
const int rows = kSelfCheckItemCount / 2;
QGridLayout* grid = new QGridLayout();
grid->setSpacing(8);
const QString names[kSelfCheckItemCount] = {
// All_Comm_FaultCode:0=通信正常,1~8=各分系统通信异常
"通信系统", "底盘电机通信", "底盘BMS通信", "机械臂通信", "空压机通信",
"柱塞泵通信", "叶片泵通信", "气体检测仪通信", "遥控器通信",
// A_LiquidLevel_Low + B_LiquidLevel_Low
"清水液位",
// MBV_D1_Sta / MBV_D2_Sta
"球阀D1开启", "球阀D1关闭", "球阀D2开启", "球阀D2关闭"
};
for (int i = 0; i < kSelfCheckItemCount; ++i) {
LedIndicator* led = new LedIndicator(names[i], center);
led->setFixedHeight(68);
led->setRadius(22);
led->setTextPixelSize(44); // 两列各 7 行,字号收窄以保证最长项“气体检测仪通信”不被裁切
QLabel* res = label("", 44, C::TEXT_SUB, false, center);
res->setFixedWidth(160);
QWidget* row = new QWidget(center);
QHBoxLayout* rowLay = new QHBoxLayout(row);
rowLay->setContentsMargins(0, 0, 0, 0);
rowLay->addWidget(led, 1);
rowLay->addWidget(res);
grid->addWidget(row, i % rows, i / rows);
m_leds.append(led);
m_results.append(res);
}
resetItems(); // 初始化 14 个自检项
centerLay->addLayout(grid);
centerLay->addSpacing(40); // 文字与进度条之间的间隙
// 进度条(位于屏幕约 3/4 高度处,文字全部在其上方)
m_progress = new QProgressBar(center);
m_progress->setRange(0, 100);
m_progress->setValue(0);
m_progress->setFixedHeight(56);
centerLay->addWidget(m_progress);
centerLay->addStretch(3); // 下方留白(更大)→ 进度条落在约 3/4 处
main->addWidget(center, 1);
// 右按钮列(高度统一为 sideBtnH,整列垂直居中)
QWidget* right = new QWidget(this);
QVBoxLayout* rightLay = new QVBoxLayout(right);
rightLay->setContentsMargins(20, 140, 20, 140);
rightLay->setSpacing(100);
QPushButton* help = makeSideBtn("操作说明", "", right);
connect(help, &QPushButton::clicked, this, &SelfCheckPage::onHelp);
QPushButton* start = makeSideBtn("启动自检", "", right);
connect(start, &QPushButton::clicked, this, &SelfCheckPage::startSelfCheck);
m_job = makeSideBtn("作业选择", "", right);
connect(m_job, &QPushButton::clicked, this, &SelfCheckPage::onJobSelect);
m_job->setEnabled(false);
rightLay->addStretch(1);
rightLay->addWidget(help);
rightLay->addWidget(start);
rightLay->addWidget(m_job);
rightLay->addStretch(1);
right->setFixedWidth(300);
main->addWidget(right);
root->addLayout(main, 1);
// 连接通信信号
connect(ctx->comm(), &CarCommunication::selfCheckItemBusy, this, &SelfCheckPage::onSelfCheckItemBusy);
connect(ctx->comm(), &CarCommunication::selfCheckItem, this, &SelfCheckPage::onSelfCheckItem);
connect(ctx->comm(), &CarCommunication::selfCheckDone, this, &SelfCheckPage::onSelfCheckDone);
}
void SelfCheckPage::showEvent(QShowEvent* ev)
{
BasePage::showEvent(ev);
if (!m_autoStarted) {
m_autoStarted = true;
startSelfCheck();
}
// 进入后聚焦:自检进行中聚焦“故障查询”;已完成后聚焦“作业选择”
QTimer::singleShot(0, this, [this]() {
if (m_job->isEnabled())
m_job->setFocus();
else
m_faultQuery->setFocus();
});
}
// 复位 14 个自检项:指示灯置灰、结果“待检测”
void SelfCheckPage::resetItems()
{
for (int i = 0; i < kSelfCheckItemCount; ++i) {
m_leds[i]->setState(LedIndicator::Off);
m_results[i]->setText("待检测");
m_results[i]->setStyleSheet(QString("color:%1;font-size:44px;").arg(C::TEXT_SUB));
}
}
void SelfCheckPage::startSelfCheck()
{
m_done = false;
m_job->setEnabled(false);
m_ignore->setEnabled(false);
m_progress->setValue(0);
m_status->setText("自检中...");
m_status->setStyleSheet(QString("color:%1;font-size:60px;font-weight:700;").arg(C::WARNING));
resetItems();
ctx()->comm()->sendSelfCheckStart();
}
void SelfCheckPage::resetAll()
{
m_autoStarted = false;
}
// 单项开始执行(球阀项要下发指令并等车端反馈,可能持续数秒):先亮黄灯、文字置“检测中”
void SelfCheckPage::onSelfCheckItemBusy(int index)
{
if (index < 0 || index >= kSelfCheckItemCount)
return;
m_leds[index]->setState(LedIndicator::Yellow);
m_results[index]->setText("检测中");
m_results[index]->setStyleSheet(QString("color:%1;font-size:44px;").arg(C::TEXT_SUB));
}
void SelfCheckPage::onSelfCheckItem(int index, bool ok)
{
if (index < 0 || index >= kSelfCheckItemCount)
return;
// 结果态
if (ok) {
m_leds[index]->setState(LedIndicator::Green);
m_results[index]->setText("正常");
m_results[index]->setStyleSheet(QString("color:%1;font-size:44px;").arg(C::SUCCESS));
} else {
m_leds[index]->setState(LedIndicator::RedBlink);
m_results[index]->setText("故障");
m_results[index]->setStyleSheet(QString("color:%1;font-size:44px;font-weight:700;").arg(C::DANGER));
}
m_progress->setValue((index + 1) * 100 / kSelfCheckItemCount);
}
void SelfCheckPage::onSelfCheckDone(bool allOk)
{
m_done = true;
if (allOk) {
m_status->setText("自检完成");
m_status->setStyleSheet(QString("color:%1;font-size:60px;font-weight:700;").arg(C::SUCCESS));
m_job->setEnabled(true);
m_job->setFocus(); // 自检完成后聚焦到“作业选择”
// 自检完成 2s 后自动进入系统首页面(原目标为作业选择页)
// QTimer::singleShot(2000, this, [this]() {
// if (m_done && isVisible())
// emit navigate(PageJob);
// });
QTimer::singleShot(2000, this, [this]() {
if (m_done && isVisible())
emit navigate(PageHome);
});
} else {
m_status->setText("无法完成自检 请检查设备");
m_status->setStyleSheet(QString("color:%1;font-size:60px;font-weight:700;").arg(C::DANGER));
startBlink(m_status, "blink");
m_ignore->setEnabled(true);
m_job->setEnabled(true);
m_faultQuery->setFocus(); // 出现故障时聚焦“故障查询”
}
}
void SelfCheckPage::onIgnoreFault()
{
emit navigate(PageHome); // 忽略故障后进入系统首页面
}
void SelfCheckPage::onJobSelect()
{
emit navigate(PageJob);
}
void SelfCheckPage::onHelp()
{
// 与系统首页面的「操作说明」同一份文案(2+1 行)
ConfirmDialog::message(this, "操作说明",
"自检过程主要检测各分系统通信、传感器信号数据是否正常、\n"
"电动球阀D1~D2是否能正常开启和关闭。\n"
"自检正常或人为点击“忽略故障”,则进入“系统首页面”。",
1000, 34);
}