#include "selfcheck.h" #include "titlebar.h" #include "ledindicator.h" #include "udpcommunication.h" #include #include #include #include #include #include #include #include #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); // 两侧按钮统一样式:字号在此统一调整;按钮会拉伸填满整列(sideBtnH 为最小高度) const int sideBtnH = 200; const QString sideBtnStyle = "font-size:60px;"; auto makeSideBtn = [&](const QString& text, const QString& variant, QWidget* parent) { QPushButton* b = button(text, variant, parent); b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); // 纵向可拉伸 b->setMinimumHeight(sideBtnH); b->setStyleSheet(sideBtnStyle); return b; }; // 左按钮列(按钮按列高平分,填满整列) 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->addWidget(m_faultQuery, 1); leftLay->addWidget(m_ignore, 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); // 10 个自检项,两列 QGridLayout* grid = new QGridLayout(); grid->setSpacing(8); const QString names[10] = { "通信系统", "底盘通信", "机械臂通信", "洗消通信", "传感器信号", "清水液位", "球阀D1开启", "球阀D1关闭", "球阀D2开启", "球阀D2关闭" }; for (int i = 0; i < 10; ++i) { LedIndicator* led = new LedIndicator(names[i], center); led->setFixedHeight(80); led->setRadius(26); led->setTextPixelSize(60); QLabel* res = label("", 50, C::TEXT_SUB, false, center); res->setFixedWidth(200); 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 % 5, i / 5); m_leds.append(led); m_results.append(res); } resetItems(); // 初始化 10 个自检项 centerLay->addLayout(grid); centerLay->addSpacing(50); // 文字与进度条之间的间隙 // 进度条(位于屏幕约 3/4 高度处,文字全部在其上方) m_progress = new QProgressBar(center); m_progress->setRange(0, 100); m_progress->setValue(0); m_progress->setFixedHeight(60); centerLay->addWidget(m_progress); centerLay->addStretch(3); // 下方留白(更大)→ 进度条落在约 3/4 处 main->addWidget(center, 1); // 右按钮列(按钮按列高平分,填满整列) QWidget* right = new QWidget(this); QVBoxLayout* rightLay = new QVBoxLayout(right); rightLay->setContentsMargins(20, 140, 20, 140); rightLay->setSpacing(140); 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->addWidget(help, 1); rightLay->addWidget(start, 1); rightLay->addWidget(m_job, 1); right->setFixedWidth(300); main->addWidget(right); root->addLayout(main, 1); // 连接通信信号 connect(ctx->comm(), &UdpCommunication::selfCheckItem, this, &SelfCheckPage::onSelfCheckItem); connect(ctx->comm(), &UdpCommunication::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(); }); } // 复位 10 个自检项:指示灯置灰、结果“待检测” void SelfCheckPage::resetItems() { for (int i = 0; i < 10; ++i) { m_leds[i]->setState(LedIndicator::Off); m_results[i]->setText("待检测"); m_results[i]->setStyleSheet(QString("color:%1;font-size:60px;").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::onSelfCheckItem(int index, bool ok) { if (index < 0 || index >= 10) return; m_leds[index]->setState(LedIndicator::Yellow); // 检测中黄闪 → 结果 // 结果态 if (ok) { m_leds[index]->setState(LedIndicator::Green); m_results[index]->setText("正常"); m_results[index]->setStyleSheet(QString("color:%1;font-size:60px;").arg(C::SUCCESS)); } else { m_leds[index]->setState(LedIndicator::RedBlink); m_results[index]->setText("异常"); m_results[index]->setStyleSheet(QString("color:%1;font-size:60px;font-weight:700;").arg(C::DANGER)); } m_progress->setValue((index + 1) * 10); } 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); // }); } 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(PageJob); } void SelfCheckPage::onJobSelect() { emit navigate(PageJob); } void SelfCheckPage::onHelp() { QMessageBox::information(this, "操作说明", "系统自检将依次检测:通信系统、底盘通信、机械臂通信、洗消通信、" "传感器信号、清水液位及电动球阀 D1/D2 的开启与关闭。\n" "全部正常后方可进入作业选择界面。"); }