260 lines
9.4 KiB
C++
260 lines
9.4 KiB
C++
#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);
|
||
}
|