Files
QT_wuhan_YT/widgets/ledindicator.cpp
T
2026-09-10 14:10:40 +08:00

104 lines
3.0 KiB
C++

#include "ledindicator.h"
#include <QPainter>
#include <QRadialGradient>
#include <QFontMetrics>
#include "global.h"
QSize LedIndicator::sizeHint() const
{
QFont f = font();
f.setPixelSize(m_textPx);
const QFontMetrics fm(f);
// 宽度 = 文字起点(圆点区 + 左侧 10px) + 文字宽度 + 右侧 10px
const int w = textLeft() + fm.horizontalAdvance(m_text) + 10;
return QSize(w, 52); // 高度与构造函数 setFixedHeight(52) 一致
}
LedIndicator::LedIndicator(const QString& text, QWidget* parent)
: QWidget(parent), m_text(text)
{
setFixedHeight(52);
setAttribute(Qt::WA_TranslucentBackground);
}
void LedIndicator::setState(State s)
{
m_state = s;
bool needBlink = (s == RedBlink || s == YellowBlink);
if (needBlink && !m_blink) {
m_blink = new QTimer(this);
m_blink->setInterval(500);
connect(m_blink, &QTimer::timeout, this, [this]() {
m_on = !m_on;
update();
});
m_blink->start();
m_on = true;
} else if (!needBlink && m_blink) {
m_blink->stop();
delete m_blink;
m_blink = nullptr;
m_on = true;
}
update();
}
void LedIndicator::setText(const QString& t)
{
m_text = t;
updateGeometry(); // 文字变了,重新按新宽度请求布局
update();
}
void LedIndicator::paintEvent(QPaintEvent*)
{
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
// 中心圆点颜色
QColor color = QColor(C::DISABLED); // 灰
switch (m_state) {
case Green: color = QColor(C::SUCCESS); break;
case Red: color = QColor(C::DANGER); break;
case Yellow: color = QColor(C::WARNING); break;
case RedBlink: color = QColor(C::DANGER); break;
case YellowBlink: color = QColor(C::WARNING); break;
default: color = QColor(C::DISABLED); break;
}
// 闪烁:40% 透明度
if ((m_state == RedBlink || m_state == YellowBlink) && !m_on)
color.setAlpha(102);
const QPointF c(m_radius + 8, height() / 2.0);
// 外发光
if (color.alpha() > 0) {
QRadialGradient glow(c, m_radius + 8);
QColor g = color; g.setAlpha(color.alpha() / 3);
QColor g0 = g; g0.setAlpha(0);
glow.setColorAt(0.0, g);
glow.setColorAt(1.0, g0);
p.setPen(Qt::NoPen);
p.setBrush(glow);
p.drawEllipse(c, m_radius + 8, m_radius + 8);
}
// 圆形主体(径向渐变)
QRadialGradient grad(c + QPointF(-m_radius / 3.0, -m_radius / 3.0), m_radius * 1.6);
QColor hi = color.lighter(130);
grad.setColorAt(0.0, hi);
grad.setColorAt(1.0, color);
p.setBrush(grad);
p.setPen(QPen(QColor(C::BORDER), 1));
p.drawEllipse(c, m_radius, m_radius);
// 文字
p.setPen(QColor(C::TEXT));
QFont f = p.font();
f.setPixelSize(m_textPx);
p.setFont(f);
const QRectF textRect(textLeft(), 0, width() - textLeft() - 10, height());
p.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, m_text);
}