160 lines
6.5 KiB
C++
160 lines
6.5 KiB
C++
#include "home.h"
|
||
#include "titlebar.h"
|
||
#include "statusstrip.h"
|
||
#include "datacard.h"
|
||
#include "confirmdialog.h"
|
||
#include "car.h"
|
||
#include <QVBoxLayout>
|
||
#include <QHBoxLayout>
|
||
#include <QGridLayout>
|
||
#include <QPushButton>
|
||
#include "global.h"
|
||
|
||
HomePage::HomePage(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(24, 20, 24, 20);
|
||
main->setSpacing(24);
|
||
|
||
// ===== 按钮统一样式(改这里即可同时调整对应的按钮)=====
|
||
// 左侧 2 个菜单按钮(字号 50px;尺寸见 addMenu 里的 setFixedSize)
|
||
const QString menuBtnStyle =
|
||
QString("QPushButton{font-size:50px;background-color:%1;color:%2;border:1px solid %3;border-radius:12px;}"
|
||
"QPushButton:hover,QPushButton:focus{background-color:%4;color:#FFFFFF;border:2px solid #8ABFFF;}")
|
||
.arg(C::PANEL_HI, C::TEXT, C::BORDER, C::PRIMARY);
|
||
// 右侧动作按钮(字号 55px;尺寸见下方各自的 setFixedSize)
|
||
const QString actionBtnStyle = "QPushButton{font-size:55px;}";
|
||
|
||
// 左侧菜单(按钮在列内水平居中、垂直整体居中,选中发亮)
|
||
QWidget* left = new QWidget(this);
|
||
QVBoxLayout* leftLay = new QVBoxLayout(left);
|
||
leftLay->setContentsMargins(10, 20, 10, 20);
|
||
leftLay->setSpacing(100);
|
||
auto addMenu = [&](const QString& t, PageId id) {
|
||
QPushButton* b = button(t, "", left);
|
||
b->setFixedSize(260, 120); // 固定尺寸(改这里同时调整 2 个菜单按钮)
|
||
b->setStyleSheet(menuBtnStyle);
|
||
connect(b, &QPushButton::clicked, this, [this, id]() { emit navigate(id); });
|
||
leftLay->addWidget(b, 0, Qt::AlignHCenter); // 不占拉伸因子,余量交给上下 stretch 均分
|
||
};
|
||
leftLay->addStretch(1);
|
||
addMenu("故障查询", PageFault);
|
||
addMenu("作业选择", PageJob);
|
||
leftLay->addStretch(1);
|
||
left->setFixedWidth(300);
|
||
main->addWidget(left);
|
||
|
||
// 中央卡片区(2×2,与作业选择页一致)
|
||
QWidget* center = new QWidget(this);
|
||
QGridLayout* grid = new QGridLayout(center);
|
||
grid->setSpacing(24);
|
||
grid->setContentsMargins(0, 0, 0, 0);
|
||
|
||
m_chassisCard = new DataCard("底盘", center);
|
||
m_chassisCard->addField("底盘电量SOC", "--");
|
||
m_chassisCard->addField("底盘电压U", "--");
|
||
|
||
m_armCard = new DataCard("机械臂", center);
|
||
// 位置/姿态两行的数值最长约 554px,超出 2×2 卡片的内容区 522px,单独把字号收小一号
|
||
m_armCard->setValueFontPx(38);
|
||
m_armCard->addField("末端位置", "--");
|
||
m_armCard->addField("末端姿态", "--");
|
||
|
||
m_washCard = new DataCard("洗消", center);
|
||
m_washCard->addField("A组分/清水液位", "--");
|
||
m_washCard->addField("泡沫箱液位", "--");
|
||
|
||
m_gasCard = new DataCard("气体检测仪", center);
|
||
m_gasCard->addField("主机状态", "--");
|
||
m_gasCard->addField("有毒物种类", "--");
|
||
m_gasCard->addField("有毒物等级", "--");
|
||
|
||
// 左列 底盘/机械臂,右列 洗消/气体检测仪
|
||
grid->addWidget(m_chassisCard, 0, 0);
|
||
grid->addWidget(m_washCard, 0, 1);
|
||
grid->addWidget(m_armCard, 1, 0);
|
||
grid->addWidget(m_gasCard, 1, 1);
|
||
main->addWidget(center, 1);
|
||
|
||
// 右侧按钮列(等分填满整列,选中发亮)
|
||
QWidget* right = new QWidget(this);
|
||
QVBoxLayout* rightLay = new QVBoxLayout(right);
|
||
rightLay->setContentsMargins(0, 0, 0, 0);
|
||
rightLay->setSpacing(24);
|
||
QPushButton* debug = button("调试维护", "", right);
|
||
debug->setFixedSize(240, 120);
|
||
debug->setStyleSheet(actionBtnStyle);
|
||
connect(debug, &QPushButton::clicked, this, [this]() { emit navigate(PageDebug); });
|
||
QPushButton* help = button("操作说明", "", right);
|
||
help->setFixedSize(240, 120);
|
||
help->setStyleSheet(actionBtnStyle);
|
||
connect(help, &QPushButton::clicked, this, &HomePage::onHelp);
|
||
QPushButton* spare = button("备用", "", right);
|
||
spare->setFixedSize(240, 120);
|
||
spare->setStyleSheet(actionBtnStyle);
|
||
spare->setEnabled(false); // 预留功能:置灰禁用,不接任何跳转
|
||
rightLay->addStretch(1);
|
||
rightLay->addWidget(debug, 0, Qt::AlignHCenter);
|
||
rightLay->addStretch(1);
|
||
rightLay->addWidget(help, 0, Qt::AlignHCenter);
|
||
rightLay->addStretch(1);
|
||
rightLay->addWidget(spare, 0, Qt::AlignHCenter);
|
||
rightLay->addStretch(1);
|
||
right->setFixedWidth(360);
|
||
main->addWidget(right);
|
||
|
||
root->addLayout(main, 1);
|
||
|
||
m_statusStrip = new StatusStrip(ctx, this);
|
||
m_statusStrip->setBackVisible(false); // 本页「返回」在右侧按钮列,底条不重复放
|
||
root->addWidget(m_statusStrip);
|
||
|
||
connect(ctx->comm(), &CarCommunication::telemetryUpdated, this, &HomePage::refresh);
|
||
refresh();
|
||
}
|
||
|
||
void HomePage::refresh()
|
||
{
|
||
const Telemetry& t = ctx()->telemetry;
|
||
|
||
// 未收到对应报文的数值统一显示 "--"(dashIf)
|
||
m_chassisCard->setField(0, dashIf(t.hasBattery, QString("%1%").arg(t.soc)));
|
||
m_chassisCard->setField(1, dashIf(t.hasBattery, QString("%1V").arg(t.volt, 0, 'f', 0)));
|
||
m_chassisCard->setFaults(t.chassisFaults);
|
||
|
||
m_armCard->setField(0, t.pos);
|
||
m_armCard->setField(1, t.pose);
|
||
// 机械臂卡没有故障行:协议里机械臂那四帧只有位置/姿态/关节角,没有故障信号
|
||
|
||
m_washCard->setField(0, dashIf(t.hasWash, QString("%1L").arg(t.levelA, 0, 'f', 0)));
|
||
m_washCard->setField(1, dashIf(t.hasWash, QString("%1L").arg(t.levelFoam, 0, 'f', 0)));
|
||
m_washCard->setAlarm(0, t.levelALow);
|
||
m_washCard->setAlarm(1, t.levelBLow);
|
||
m_washCard->setFaults(washCardFaults(t));
|
||
|
||
m_gasCard->setField(0, gasHostLabel(t));
|
||
m_gasCard->setField(1, t.gasType); // 有毒物种类,未收到报文时本身就是 "--"
|
||
m_gasCard->setField(2, t.gasLevel); // 有毒物等级
|
||
m_gasCard->setAlarm(0, t.gasHost == "fault");
|
||
m_gasCard->setFaults(t.detectorFaults);
|
||
}
|
||
|
||
void HomePage::onHelp()
|
||
{
|
||
// 正文按 2+1 断句。字号 34 时最长一行 918px,正文区 944px,不会被 wordWrap 二次折行
|
||
ConfirmDialog::message(this, "操作说明",
|
||
"自检过程主要检测各分系统通信、传感器信号数据是否正常、\n"
|
||
"电动球阀D1~D2是否能正常开启和关闭。\n"
|
||
"自检正常或人为点击“忽略故障”,则进入“系统首页面”。",
|
||
1000, 34);
|
||
}
|