GrabBag/App/WheelMeasure/WheelMeasureApp/widgets/MeasureResultListWidget.cpp
2025-12-27 09:34:02 +08:00

273 lines
9.8 KiB
C++

#include "MeasureResultListWidget.h"
#include <QDateTime>
// ============ DeviceResultCard 实现 ============
DeviceResultCard::DeviceResultCard(const QString& deviceName, QWidget* parent)
: QFrame(parent)
, m_deviceName(deviceName)
{
setupUI();
}
DeviceResultCard::~DeviceResultCard()
{
}
void DeviceResultCard::setupUI()
{
// 设置卡片样式
setStyleSheet(
"DeviceResultCard { "
" background-color: rgb(47, 48, 52); "
" border: 1px solid rgb(60, 62, 68); "
" border-radius: 8px; "
" padding: 10px; "
"} "
"DeviceResultCard:hover { "
" border: 1px solid rgb(80, 82, 88); "
"}"
);
setMinimumHeight(120);
setMaximumHeight(160);
// 主布局:水平布局(左侧名称 | 右侧数据)
QHBoxLayout* mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(12, 8, 12, 8);
mainLayout->setSpacing(15);
// 左侧:设备名称和状态
QVBoxLayout* leftLayout = new QVBoxLayout();
leftLayout->setSpacing(4);
m_nameLabel = new QLabel(m_deviceName, this);
m_nameLabel->setStyleSheet("QLabel { color: rgb(221, 225, 233); font-size: 16px; background: transparent; }");
m_nameLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_nameLabel->setMinimumWidth(80);
m_statusLabel = new QLabel(QString::fromUtf8("等待检测"), this);
m_statusLabel->setStyleSheet("QLabel { color: rgb(150, 150, 150); font-size: 16px; background: transparent; }");
m_statusLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
leftLayout->addStretch();
leftLayout->addWidget(m_nameLabel);
leftLayout->addWidget(m_statusLabel);
leftLayout->addStretch();
mainLayout->addLayout(leftLayout);
// 分隔线
QFrame* separator = new QFrame(this);
separator->setFrameShape(QFrame::VLine);
separator->setStyleSheet("QFrame { color: rgb(60, 62, 68); }");
mainLayout->addWidget(separator);
// 右侧:纵向显示数据
QVBoxLayout* rightLayout = new QVBoxLayout();
rightLayout->setSpacing(2);
// 拱高
m_heightLabel = new QLabel(QString::fromUtf8("拱高: -- mm"), this);
m_heightLabel->setStyleSheet("QLabel { color: rgb(100, 200, 100); font-size: 16px; background: transparent; }");
// 拱点位置
m_archPosLabel = new QLabel(QString::fromUtf8("拱点: X:-- Y:-- Z:--"), this);
m_archPosLabel->setStyleSheet("QLabel { color: rgb(180, 180, 180); font-size: 14px; background: transparent; }");
// 上位置
m_upPosLabel = new QLabel(QString::fromUtf8("上点: X:-- Y:-- Z:--"), this);
m_upPosLabel->setStyleSheet("QLabel { color: rgb(180, 180, 180); font-size: 14px; background: transparent; }");
// 下位置
m_downPosLabel = new QLabel(QString::fromUtf8("下点: X:-- Y:-- Z:--"), this);
m_downPosLabel->setStyleSheet("QLabel { color: rgb(180, 180, 180); font-size: 14px; background: transparent; }");
// 时间戳
m_timestampLabel = new QLabel("", this);
m_timestampLabel->setStyleSheet("QLabel { color: rgb(120, 120, 120); font-size: 14px; background: transparent; }");
rightLayout->addStretch();
rightLayout->addWidget(m_heightLabel);
rightLayout->addWidget(m_archPosLabel);
rightLayout->addWidget(m_upPosLabel);
rightLayout->addWidget(m_downPosLabel);
rightLayout->addWidget(m_timestampLabel);
rightLayout->addStretch();
mainLayout->addLayout(rightLayout, 1);
}
void DeviceResultCard::updateResult(const WheelMeasureData& data, bool isValid)
{
if (isValid) {
// 更新拱高
m_heightLabel->setText(QString::fromUtf8("拱高: %1 mm").arg(data.archToCenterHeight, 0, 'f', 2));
m_heightLabel->setStyleSheet("QLabel { color: rgb(100, 200, 100); font-size: 16px; background: transparent; }");
// 更新拱点位置
QString archPosText = QString::fromUtf8("拱点: X:%1 Y:%2 Z:%3")
.arg(data.wheelArchPosX, 0, 'f', 2)
.arg(data.wheelArchPosY, 0, 'f', 2)
.arg(data.wheelArchPosZ, 0, 'f', 2);
m_archPosLabel->setText(archPosText);
// 更新上位置
QString upPosText = QString::fromUtf8("上点: X:%1 Y:%2 Z:%3")
.arg(data.wheelUpPosX, 0, 'f', 2)
.arg(data.wheelUpPosY, 0, 'f', 2)
.arg(data.wheelUpPosZ, 0, 'f', 2);
m_upPosLabel->setText(upPosText);
// 更新下位置
QString downPosText = QString::fromUtf8("下点: X:%1 Y:%2 Z:%3")
.arg(data.wheelDownPosX, 0, 'f', 2)
.arg(data.wheelDownPosY, 0, 'f', 2)
.arg(data.wheelDownPosZ, 0, 'f', 2);
m_downPosLabel->setText(downPosText);
// 更新时间戳
QString timestamp = data.timestamp.isEmpty()
? QDateTime::currentDateTime().toString("HH:mm:ss")
: data.timestamp;
m_timestampLabel->setText(timestamp);
// 更新状态
m_statusLabel->setText(QString::fromUtf8("检测成功"));
m_statusLabel->setStyleSheet("QLabel { color: rgb(100, 200, 100); font-size: 16px; background: transparent; }");
} else {
// 无效结果
m_heightLabel->setText(QString::fromUtf8("拱高: -- mm"));
m_heightLabel->setStyleSheet("QLabel { color: rgb(200, 100, 100); font-size: 16px; background: transparent; }");
m_archPosLabel->setText(QString::fromUtf8("拱点: X:-- Y:-- Z:--"));
m_upPosLabel->setText(QString::fromUtf8("上点: X:-- Y:-- Z:--"));
m_downPosLabel->setText(QString::fromUtf8("下点: X:-- Y:-- Z:--"));
QString timestamp = QDateTime::currentDateTime().toString("HH:mm:ss");
m_timestampLabel->setText(timestamp);
m_statusLabel->setText(QString::fromUtf8("检测失败"));
m_statusLabel->setStyleSheet("QLabel { color: rgb(200, 100, 100); font-size: 16px; background: transparent; }");
}
}
void DeviceResultCard::clearResult()
{
m_heightLabel->setText(QString::fromUtf8("拱高: -- mm"));
m_heightLabel->setStyleSheet("QLabel { color: rgb(150, 150, 150); font-size: 16px; background: transparent; }");
m_archPosLabel->setText(QString::fromUtf8("拱点: X:-- Y:-- Z:--"));
m_upPosLabel->setText(QString::fromUtf8("上点: X:-- Y:-- Z:--"));
m_downPosLabel->setText(QString::fromUtf8("下点: X:-- Y:-- Z:--"));
m_timestampLabel->setText("");
m_statusLabel->setText(QString::fromUtf8("等待检测"));
m_statusLabel->setStyleSheet("QLabel { color: rgb(150, 150, 150); font-size: 16px; background: transparent; }");
}
// ============ MeasureResultListWidget 实现 ============
MeasureResultListWidget::MeasureResultListWidget(QWidget* parent)
: QWidget(parent)
{
setupUI();
}
MeasureResultListWidget::~MeasureResultListWidget()
{
}
void MeasureResultListWidget::setupUI()
{
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
// 创建滚动区域
m_scrollArea = new QScrollArea(this);
m_scrollArea->setWidgetResizable(true);
m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_scrollArea->setStyleSheet(
"QScrollArea { "
" background-color: rgb(38, 40, 47); "
" border: none; "
"} "
"QScrollBar:vertical { "
" background-color: rgb(38, 40, 47); "
" width: 8px; "
"} "
"QScrollBar::handle:vertical { "
" background-color: rgb(80, 82, 88); "
" border-radius: 4px; "
" min-height: 20px; "
"} "
"QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { "
" height: 0px; "
"}"
);
// 创建内容容器
m_contentWidget = new QWidget();
m_contentWidget->setStyleSheet("background-color: rgb(38, 40, 47);");
m_contentLayout = new QVBoxLayout(m_contentWidget);
m_contentLayout->setContentsMargins(8, 8, 8, 8);
m_contentLayout->setSpacing(8);
m_contentLayout->addStretch();
m_scrollArea->setWidget(m_contentWidget);
mainLayout->addWidget(m_scrollArea);
}
void MeasureResultListWidget::setDeviceList(const QStringList& deviceNames)
{
// 清除现有卡片
for (auto card : m_deviceCards.values()) {
m_contentLayout->removeWidget(card);
delete card;
}
m_deviceCards.clear();
// 创建新卡片
for (const QString& name : deviceNames) {
DeviceResultCard* card = new DeviceResultCard(name, m_contentWidget);
m_deviceCards[name] = card;
// 插入到stretch之前
m_contentLayout->insertWidget(m_contentLayout->count() - 1, card);
}
}
DeviceResultCard* MeasureResultListWidget::findOrCreateCard(const QString& deviceName)
{
if (m_deviceCards.contains(deviceName)) {
return m_deviceCards[deviceName];
}
// 如果不存在,创建新卡片
DeviceResultCard* card = new DeviceResultCard(deviceName, m_contentWidget);
m_deviceCards[deviceName] = card;
// 插入到stretch之前
m_contentLayout->insertWidget(m_contentLayout->count() - 1, card);
return card;
}
void MeasureResultListWidget::updateDeviceResult(const QString& deviceName, const WheelMeasureData& data, bool isValid)
{
DeviceResultCard* card = findOrCreateCard(deviceName);
if (card) {
card->updateResult(data, isValid);
}
}
void MeasureResultListWidget::clearAllResults()
{
for (auto card : m_deviceCards.values()) {
card->clearResult();
}
}
void MeasureResultListWidget::clearDeviceResult(const QString& deviceName)
{
if (m_deviceCards.contains(deviceName)) {
m_deviceCards[deviceName]->clearResult();
}
}