新版布局
This commit is contained in:
+68
-26
@@ -2,10 +2,22 @@
|
||||
#include "ledindicator.h"
|
||||
#include "appcontext.h"
|
||||
#include "car.h"
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include "global.h"
|
||||
|
||||
namespace {
|
||||
// 首页/作业选择“中央卡片区”的左边缘:主区左内边距 24 + 左列 300 + 间距 24
|
||||
const int kCardLeft = 300;
|
||||
// LedIndicator 的文字起点(圆点区宽度):radius(16)×2 + 左侧留白 18,见 LedIndicator::textLeft()
|
||||
const int kCommTextLeft = 50;
|
||||
// 顶栏左右区宽度。左区要容下最长的一条异常“气体检测仪通信异常”
|
||||
// (9 个全角字 × 43px = 387):274(左侧留白) + 50 + 387 + 10 = 721;
|
||||
// 上限 726——居中标题的左边缘在 750,再宽就压上去了。
|
||||
const int kSideW = 726;
|
||||
} // namespace
|
||||
|
||||
TitleBar::TitleBar(AppContext* ctx, QWidget* parent)
|
||||
: QWidget(parent), m_ctx(ctx)
|
||||
{
|
||||
@@ -14,16 +26,18 @@ TitleBar::TitleBar(AppContext* ctx, QWidget* parent)
|
||||
setStyleSheet(QString("QWidget#TitleBar{background-color:%1;border-bottom:1px solid %2;}")
|
||||
.arg(C::PANEL, C::BORDER));
|
||||
|
||||
// 左侧区(车载端通信状态)
|
||||
// 左侧区(车载端通信状态,固定一行,不轮播)
|
||||
QWidget* leftBox = new QWidget(this);
|
||||
QHBoxLayout* leftLay = new QHBoxLayout(leftBox);
|
||||
leftLay->setContentsMargins(260, 0, 0, 0);
|
||||
leftLay->setSpacing(20);
|
||||
m_comm = new LedIndicator("通信正常", leftBox);
|
||||
m_comm->setFixedHeight(80); // 容纳放大后的文字,避免上下裁切
|
||||
m_comm->setTextPixelSize(45);
|
||||
leftLay->setSpacing(0); // 只有指示器 + 弹簧,留间距只会白白吃掉文字宽度
|
||||
m_comm = new LedIndicator("系统通信正常", leftBox);
|
||||
// 高度沿用 LedIndicator 默认的 52:43px 字与 48px 直径的圆点外发光刚好容得下
|
||||
m_comm->setTextPixelSize(45); // 与右侧“遥控器正常”同字号
|
||||
m_comm->setBlinkText(true); // 异常时文字跟着圆点一起闪
|
||||
m_comm->setState(LedIndicator::Green);
|
||||
leftLay->addWidget(m_comm);
|
||||
leftLay->setContentsMargins(kCardLeft - 24 - kCommTextLeft, 0, 0, 0);
|
||||
|
||||
leftLay->addWidget(m_comm, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
leftLay->addStretch(1);
|
||||
|
||||
// 右侧区(遥控器状态:链路 + 电量)
|
||||
@@ -37,35 +51,37 @@ TitleBar::TitleBar(AppContext* ctx, QWidget* parent)
|
||||
m_rc->setTextPixelSize(45);
|
||||
m_rc->setState(LedIndicator::RedBlink);
|
||||
rightLay->addWidget(m_rc);
|
||||
m_rcBat = new QLabel("--%", rightBox);
|
||||
m_rcBat->setStyleSheet(QString("color:%1;font-size:60px;").arg(C::TEXT_SUB));
|
||||
m_rcBat = new QLabel(rightBox);
|
||||
m_rcBat->setAlignment(Qt::AlignCenter);
|
||||
rightLay->addWidget(m_rcBat);
|
||||
setRcBattery(-1);
|
||||
|
||||
// 左右两侧等宽 → 中间标题恰好居中于屏幕
|
||||
// 左区需 260(左边距)+ 240(圆点区与留白 60 + 文字 4×45)= 500
|
||||
// 右区需 285(圆点区与留白 60 + 文字 5×45)+ 30 + 130(电量)+ 20 = 465
|
||||
const int sideW = 520;
|
||||
leftBox->setFixedWidth(sideW);
|
||||
rightBox->setFixedWidth(sideW);
|
||||
// 左右两侧区等宽(宽度见 kSideW:左区要放得下最长的一条异常)
|
||||
leftBox->setFixedWidth(kSideW);
|
||||
rightBox->setFixedWidth(kSideW);
|
||||
|
||||
// 标题(居中)
|
||||
m_title = new QLabel("", this);
|
||||
m_title->setAlignment(Qt::AlignCenter);
|
||||
m_title->setStyleSheet(QString("color:%1;font-size:60px;font-weight:700;").arg(C::TEXT));
|
||||
|
||||
QHBoxLayout* lay = new QHBoxLayout(this);
|
||||
// 用 QGridLayout 让标题横跨整条顶栏居中,而不是夹在左右两区之间拉伸:
|
||||
// 后者下标题的可用宽度 = 1920 - 24×2 - 两侧区宽×2,左区为了放下通信文字一加宽,
|
||||
// 标题就被挤窄甚至裁字;横跨三列后标题始终居中于屏幕,两侧区多宽都不影响它。
|
||||
QGridLayout* lay = new QGridLayout(this);
|
||||
lay->setContentsMargins(24, 6, 24, 6);
|
||||
lay->setSpacing(0);
|
||||
lay->addWidget(leftBox);
|
||||
lay->addWidget(m_title, 1);
|
||||
lay->addWidget(rightBox);
|
||||
lay->addWidget(leftBox, 0, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
lay->addWidget(rightBox, 0, 2, Qt::AlignRight | Qt::AlignVCenter);
|
||||
lay->addWidget(m_title, 0, 0, 1, 3, Qt::AlignCenter);
|
||||
|
||||
// 车载端通信状态刷新
|
||||
connect(m_ctx->comm(), &CarCommunication::commOkChanged, this, [this](bool ok) {
|
||||
if (ok) { m_comm->setText("通信正常"); m_comm->setState(LedIndicator::Green); }
|
||||
else { m_comm->setText("通信异常"); m_comm->setState(LedIndicator::RedBlink); }
|
||||
});
|
||||
// 车载端通信状态:只在文案变化时由通信层通知,这里不做任何轮播。
|
||||
connect(m_ctx->comm(), &CarCommunication::commTextChanged,
|
||||
this, &TitleBar::onCommTextChanged);
|
||||
|
||||
// 每个页面各有自己的顶条实例,构造时通信层可能早就报过状态了;而 commTextChanged
|
||||
// 只在内容变化时才发,所以这里必须先取一次当前值,否则新页面的顶条会一直停在构造时的初值。
|
||||
updateComm();
|
||||
|
||||
// 遥控器链路与电量刷新
|
||||
connect(m_ctx->rc(), &RcCommunication::linkChanged, this, &TitleBar::onRcLink);
|
||||
@@ -73,6 +89,22 @@ TitleBar::TitleBar(AppContext* ctx, QWidget* parent)
|
||||
onRcLink(m_ctx->rc()->linkOk());
|
||||
}
|
||||
|
||||
void TitleBar::onCommTextChanged()
|
||||
{
|
||||
updateComm();
|
||||
}
|
||||
|
||||
// 左区固定显示通信状态:链路断或带 All_Comm_FaultCode 就红色闪烁,其余绿灯。
|
||||
// 文案由通信层渲染(Telemetry::commText),这里只决定配色。
|
||||
void TitleBar::updateComm()
|
||||
{
|
||||
const Telemetry& t = m_ctx->telemetry;
|
||||
const bool warn = !t.commOk || t.commCode != 0;
|
||||
m_comm->setText(t.commText);
|
||||
m_comm->setState(warn ? LedIndicator::RedBlink : LedIndicator::Green);
|
||||
m_comm->setTextColor(QColor(warn ? C::DANGER : C::TEXT)); // 只有异常才用红色警示
|
||||
}
|
||||
|
||||
void TitleBar::setTitle(const QString& title)
|
||||
{
|
||||
m_title->setText(title);
|
||||
@@ -86,11 +118,21 @@ void TitleBar::onRcLink(bool ok)
|
||||
} else {
|
||||
m_rc->setText("遥控器断开");
|
||||
m_rc->setState(LedIndicator::RedBlink);
|
||||
m_rcBat->setText("--%");
|
||||
setRcBattery(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void TitleBar::setRcBattery(int battery)
|
||||
{
|
||||
// battery < 0 表示链路断开,无电量可显示
|
||||
const bool valid = battery >= 0;
|
||||
const QString color = !valid ? C::TEXT_SUB
|
||||
: (battery <= 20 ? C::DANGER : C::SUCCESS);
|
||||
m_rcBat->setText(valid ? QString("%1%").arg(battery) : QString("--%"));
|
||||
m_rcBat->setStyleSheet(QString("color:%1;font-size:50px;").arg(color));
|
||||
}
|
||||
|
||||
void TitleBar::onRcFrame(const RcFrame& f)
|
||||
{
|
||||
m_rcBat->setText(QString("%1%").arg(f.battery));
|
||||
setRcBattery(f.battery);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user