298 lines
10 KiB
C++
298 lines
10 KiB
C++
#include "resultitem.h"
|
|
#include "ui_resultitem.h"
|
|
|
|
#include <QStringList>
|
|
#include <QFrame>
|
|
#include <cmath>
|
|
|
|
namespace
|
|
{
|
|
void setResultTextStyle(Ui::ResultItem* ui)
|
|
{
|
|
const QString titleStyle =
|
|
QStringLiteral("color: rgb(239, 241, 245); background-color: rgb(37, 38, 42); font-size: 20px; font-weight: 600;");
|
|
const QString valueStyle =
|
|
QStringLiteral("color: rgb(255, 255, 255); background-color: rgb(37, 38, 42); font-size: 26px; font-weight: 700;");
|
|
|
|
if (ui->lb_id_t) ui->lb_id_t->setStyleSheet(titleStyle);
|
|
if (ui->lb_time_t) ui->lb_time_t->setStyleSheet(titleStyle);
|
|
if (ui->lb_count_t) ui->lb_count_t->setStyleSheet(titleStyle);
|
|
if (ui->lb_size_t) ui->lb_size_t->setStyleSheet(titleStyle);
|
|
if (ui->lb_status_t) ui->lb_status_t->setStyleSheet(titleStyle);
|
|
|
|
if (ui->label_id) ui->label_id->setStyleSheet(valueStyle);
|
|
if (ui->label_time) ui->label_time->setStyleSheet(valueStyle);
|
|
if (ui->label_count) ui->label_count->setStyleSheet(valueStyle);
|
|
if (ui->label_size) ui->label_size->setStyleSheet(valueStyle);
|
|
if (ui->label_status) ui->label_status->setStyleSheet(valueStyle);
|
|
}
|
|
|
|
QString failedText(const CtrlDetectionFrame& frame)
|
|
{
|
|
return frame.message.isEmpty() ? QStringLiteral("检测失败") : frame.message;
|
|
}
|
|
|
|
bool hasValidPhysicalHeight(const CtrlDetectionBox& box)
|
|
{
|
|
return box.hasPhysicalHeight &&
|
|
std::isfinite(static_cast<double>(box.physicalHeightMm)) &&
|
|
box.physicalHeightMm > 0.0f;
|
|
}
|
|
|
|
QString physicalHeightErrorText(const CtrlDetectionFrame& frame,
|
|
const CtrlDetectionBox& box)
|
|
{
|
|
if (!frame.success)
|
|
return failedText(frame);
|
|
|
|
QStringList parts;
|
|
parts << QStringLiteral("未测到物理高度");
|
|
|
|
const QString status = box.matchStatus.trimmed();
|
|
if (!status.isEmpty() && status != QStringLiteral("ok"))
|
|
parts << QStringLiteral("状态:%1").arg(status);
|
|
|
|
if (!box.hasStereoMatch)
|
|
parts << QStringLiteral("双目未匹配");
|
|
else if (!box.trusted)
|
|
parts << QStringLiteral("结果不可信");
|
|
|
|
if (box.hasPhysicalHeight)
|
|
parts << QStringLiteral("高度无效:%1 mm").arg(box.physicalHeightMm, 0, 'f', 2);
|
|
|
|
return parts.join(QStringLiteral(" "));
|
|
}
|
|
|
|
void setStatusErrorStyle(Ui::ResultItem* ui)
|
|
{
|
|
if (!ui || !ui->label_status)
|
|
return;
|
|
|
|
ui->label_status->setStyleSheet(QStringLiteral(
|
|
"color: rgb(255, 105, 105); background-color: rgb(37, 38, 42); font-size: 22px; font-weight: 700;"));
|
|
}
|
|
|
|
QString oneDistanceText(const CtrlDetectionDistance& d)
|
|
{
|
|
const double meters = d.distanceMm / 1000.0;
|
|
return QStringLiteral("%1m").arg(meters, 0, 'f', 3);
|
|
}
|
|
|
|
QString oneDistanceMmText(const CtrlDetectionDistance& d)
|
|
{
|
|
return QStringLiteral("%1 mm").arg(d.distanceMm, 0, 'f', 2);
|
|
}
|
|
|
|
bool isDistanceDisplayable(const CtrlDetectionDistance& distance)
|
|
{
|
|
return distance.fromId >= 0;
|
|
}
|
|
|
|
QString distanceText(const CtrlDetectionFrame& frame, int targetIndex)
|
|
{
|
|
if (targetIndex >= 0 && targetIndex < static_cast<int>(frame.distances.size()))
|
|
{
|
|
const CtrlDetectionDistance& distance = frame.distances[static_cast<size_t>(targetIndex)];
|
|
return isDistanceDisplayable(distance)
|
|
? oneDistanceText(distance)
|
|
: QStringLiteral("未测到距离");
|
|
}
|
|
|
|
QStringList distanceParts;
|
|
for (size_t i = 0; i < frame.distances.size(); ++i)
|
|
{
|
|
if (isDistanceDisplayable(frame.distances[i]))
|
|
distanceParts << oneDistanceText(frame.distances[i]);
|
|
}
|
|
return distanceParts.isEmpty()
|
|
? QStringLiteral("未测到距离")
|
|
: distanceParts.join(" ");
|
|
}
|
|
|
|
QString distanceMmText(const CtrlDetectionFrame& frame, int targetIndex)
|
|
{
|
|
if (targetIndex >= 0 && targetIndex < static_cast<int>(frame.distances.size()))
|
|
{
|
|
const CtrlDetectionDistance& distance = frame.distances[static_cast<size_t>(targetIndex)];
|
|
return isDistanceDisplayable(distance)
|
|
? oneDistanceMmText(distance)
|
|
: QStringLiteral("未测到距离");
|
|
}
|
|
|
|
QStringList distanceParts;
|
|
for (size_t i = 0; i < frame.distances.size(); ++i)
|
|
{
|
|
if (isDistanceDisplayable(frame.distances[i]))
|
|
distanceParts << oneDistanceMmText(frame.distances[i]);
|
|
}
|
|
return distanceParts.isEmpty()
|
|
? QStringLiteral("未测到距离")
|
|
: distanceParts.join(" ");
|
|
}
|
|
|
|
QString distanceIndexText(const CtrlDetectionFrame& frame, int targetIndex)
|
|
{
|
|
const int total = static_cast<int>(frame.distances.size());
|
|
if (targetIndex >= 0 && targetIndex < total)
|
|
{
|
|
const CtrlDetectionDistance& d = frame.distances[static_cast<size_t>(targetIndex)];
|
|
if (isDistanceDisplayable(d))
|
|
return QString::number(d.fromId + 1);
|
|
}
|
|
return QStringLiteral("-");
|
|
}
|
|
|
|
QString precisionDistanceIndexText(const CtrlDetectionFrame& frame, int targetIndex)
|
|
{
|
|
const int total = static_cast<int>(frame.distances.size());
|
|
if (targetIndex >= 0 && targetIndex < total)
|
|
{
|
|
const CtrlDetectionDistance& d = frame.distances[static_cast<size_t>(targetIndex)];
|
|
if (d.fromId >= 0 && d.toId >= 0)
|
|
return QStringLiteral("%1-%2").arg(d.fromId + 1).arg(d.toId + 1);
|
|
if (d.fromId >= 0)
|
|
return QString::number(d.fromId + 1);
|
|
if (d.toId >= 0)
|
|
return QString::number(d.toId + 1);
|
|
}
|
|
return QStringLiteral("-");
|
|
}
|
|
}
|
|
|
|
ResultItem::ResultItem(QWidget* parent)
|
|
: QWidget(parent)
|
|
, ui(new Ui::ResultItem)
|
|
{
|
|
ui->setupUi(this);
|
|
setAttribute(Qt::WA_StyledBackground, true);
|
|
setAutoFillBackground(true);
|
|
setStyleSheet(QStringLiteral(
|
|
"QWidget#ResultItem { background-color: rgb(37, 38, 42); border: 6px solid #191A1C; border-radius: 0px; }"
|
|
"QFrame#frame { background-color: rgb(37, 38, 42); border: none; }"
|
|
"QLabel { background-color: rgb(37, 38, 42); color: rgb(255, 255, 255); }"));
|
|
if (ui->frame)
|
|
ui->frame->setFrameShape(QFrame::NoFrame);
|
|
if (ui->lb_time_t) ui->lb_time_t->hide();
|
|
if (ui->label_time) ui->label_time->hide();
|
|
if (ui->lb_count_t) ui->lb_count_t->hide();
|
|
if (ui->label_count) ui->label_count->hide();
|
|
if (ui->lb_size_t) ui->lb_size_t->hide();
|
|
if (ui->label_size) ui->label_size->hide();
|
|
if (ui->grid && ui->lb_status_t && ui->label_status)
|
|
{
|
|
ui->grid->removeWidget(ui->lb_status_t);
|
|
ui->grid->removeWidget(ui->label_status);
|
|
ui->grid->addWidget(ui->lb_status_t, 1, 0);
|
|
ui->grid->addWidget(ui->label_status, 1, 1);
|
|
ui->grid->setColumnStretch(0, 0);
|
|
ui->grid->setColumnStretch(1, 1);
|
|
ui->grid->setColumnMinimumWidth(0, 52);
|
|
}
|
|
if (ui->label_id)
|
|
ui->label_id->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
|
if (ui->label_status)
|
|
{
|
|
ui->label_status->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
|
ui->label_status->setWordWrap(true);
|
|
}
|
|
}
|
|
|
|
ResultItem::~ResultItem()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void ResultItem::setResultData(int targetIndex,
|
|
const CtrlDetectionFrame& frame,
|
|
DisplayMode mode)
|
|
{
|
|
const bool precisionMode = (mode == DisplayMode::Precision);
|
|
const bool precisionDistanceMode = (mode == DisplayMode::PrecisionDistance);
|
|
const QString finalPrefix =
|
|
(frame.isFinalResult && frame.saveIndex > 0)
|
|
? QStringLiteral("#%1 ").arg(frame.saveIndex)
|
|
: QString();
|
|
setResultTextStyle(ui);
|
|
setMinimumHeight((precisionMode || precisionDistanceMode) ? 104 : 108);
|
|
|
|
if (ui->lb_id_t)
|
|
ui->lb_id_t->setText(frame.isFinalResult ? QStringLiteral("FINAL")
|
|
: QStringLiteral("ID"));
|
|
if (ui->lb_status_t)
|
|
{
|
|
if (mode == DisplayMode::Distance)
|
|
ui->lb_status_t->setText(QStringLiteral("距离"));
|
|
else if (precisionDistanceMode)
|
|
ui->lb_status_t->setText(QStringLiteral("杆间距"));
|
|
else if (precisionMode)
|
|
ui->lb_status_t->setText(QStringLiteral("物理高度"));
|
|
else
|
|
ui->lb_status_t->setText(QStringLiteral("状态"));
|
|
}
|
|
|
|
if (ui->label_id)
|
|
{
|
|
if (precisionMode && targetIndex >= 0)
|
|
ui->label_id->setText(finalPrefix + QString("%1/%2")
|
|
.arg(targetIndex + 1)
|
|
.arg(static_cast<int>(frame.boxes.size())));
|
|
else if (precisionDistanceMode)
|
|
{
|
|
ui->label_id->setText(finalPrefix + precisionDistanceIndexText(frame, targetIndex));
|
|
}
|
|
else if (mode == DisplayMode::Distance)
|
|
{
|
|
ui->label_id->setText(finalPrefix + distanceIndexText(frame, targetIndex));
|
|
}
|
|
else
|
|
ui->label_id->setText(finalPrefix + QStringLiteral("0/0"));
|
|
}
|
|
|
|
if (mode == DisplayMode::Distance || precisionDistanceMode)
|
|
{
|
|
if (ui->label_status)
|
|
{
|
|
ui->label_status->setText(frame.success
|
|
? (precisionDistanceMode
|
|
? distanceMmText(frame, targetIndex)
|
|
: distanceText(frame, targetIndex))
|
|
: failedText(frame));
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (ui->label_status)
|
|
{
|
|
if (targetIndex >= 0 && targetIndex < static_cast<int>(frame.boxes.size()))
|
|
{
|
|
const CtrlDetectionBox& b = frame.boxes[static_cast<size_t>(targetIndex)];
|
|
if (hasValidPhysicalHeight(b))
|
|
{
|
|
ui->label_status->setText(QStringLiteral("%1 mm")
|
|
.arg(b.physicalHeightMm, 0, 'f', 2));
|
|
}
|
|
else if (precisionMode)
|
|
{
|
|
ui->label_status->setText(physicalHeightErrorText(frame, b));
|
|
setStatusErrorStyle(ui);
|
|
}
|
|
else
|
|
{
|
|
const QString text = QStringLiteral("score=%1 w=%2 h=%3")
|
|
.arg(b.score, 0, 'f', 3)
|
|
.arg(b.width)
|
|
.arg(b.height);
|
|
ui->label_status->setText(text);
|
|
}
|
|
}
|
|
else if (!frame.success)
|
|
{
|
|
ui->label_status->setText(failedText(frame));
|
|
}
|
|
else
|
|
{
|
|
ui->label_status->setText(QStringLiteral("未检测到目标"));
|
|
}
|
|
}
|
|
}
|