935 lines
44 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dialogalgoarg.h"
#include "ui_dialogalgoarg.h"
#include <QCheckBox>
#include <QDoubleValidator>
#include <QFormLayout>
#include <QFont>
#include <QIntValidator>
#include <QLineEdit>
#include <QList>
#include <QPainter>
#include <QPen>
#include <QPushButton>
#include <QRectF>
#include <QScrollArea>
#include <QTabWidget>
#include <QTimer>
#include <algorithm>
#include <cmath>
#include "ParkingSpaceGuidePresenter.h"
#include "PathManager.h"
#include "StyledMessageBox.h"
class RoiPreviewWidget final : public QWidget
{
public:
explicit RoiPreviewWidget(QWidget* parent = nullptr)
: QWidget(parent)
{
setMinimumSize(420, 360);
}
void SetImage(const QImage& image)
{
m_image = image;
update();
}
void SetRoi(const QRectF& roi, const QString& label)
{
m_roi = roi;
m_label = label;
update();
}
void SetStatus(const QString& status)
{
m_status = status;
update();
}
protected:
void paintEvent(QPaintEvent*) override
{
QPainter painter(this);
painter.fillRect(rect(), QColor(20, 22, 25));
painter.setPen(QColor(221, 225, 233));
const QRect content = rect().adjusted(12, 36, -12, -12);
painter.drawText(QRect(12, 8, width() - 24, 22),
Qt::AlignLeft | Qt::AlignVCenter,
m_label.isEmpty()
? QStringLiteral("实时图像")
: m_label);
if (m_image.isNull()) {
painter.drawText(content, Qt::AlignCenter,
m_status.isEmpty()
? QStringLiteral("等待相机图像")
: m_status);
return;
}
QSize targetSize = m_image.size();
targetSize.scale(content.size(), Qt::KeepAspectRatio);
const QRect imageRect(
content.center().x() - targetSize.width() / 2,
content.center().y() - targetSize.height() / 2,
targetSize.width(), targetSize.height());
painter.drawImage(imageRect, m_image);
const QRectF normalizedRoi(
std::clamp(m_roi.x(), 0.0, 1.0),
std::clamp(m_roi.y(), 0.0, 1.0),
std::clamp(m_roi.width(), 0.0, 1.0),
std::clamp(m_roi.height(), 0.0, 1.0));
const QRectF roiRect(
imageRect.x() + normalizedRoi.x() * imageRect.width(),
imageRect.y() + normalizedRoi.y() * imageRect.height(),
normalizedRoi.width() * imageRect.width(),
normalizedRoi.height() * imageRect.height());
painter.setPen(QPen(QColor(255, 205, 65), 3));
painter.drawRect(roiRect);
}
private:
QImage m_image;
QRectF m_roi;
QString m_label;
QString m_status;
};
DialogAlgoArg::DialogAlgoArg(QWidget* parent)
: QDialog(parent)
, ui(new Ui::DialogAlgoArg)
{
ui->setupUi(this);
setWindowTitle(QStringLiteral("停机引导参数设置"));
if (ui->label_title) {
ui->label_title->setText(QStringLiteral("停机引导参数设置"));
}
setMinimumSize(1260, 760);
resize(1260, 760);
ui->tabWidget->setGeometry(40, 80, 690, 600);
ui->btnReset->setGeometry(40, 695, 120, 45);
ui->btnApply->setGeometry(390, 695, 100, 45);
ui->btnOK->setGeometry(510, 695, 100, 45);
ui->btnCancel->setGeometry(630, 695, 100, 45);
m_roiPreview = new RoiPreviewWidget(this);
m_roiPreview->setGeometry(760, 80, 460, 600);
m_roiPreview->hide();
m_previewTimer = new QTimer(this);
m_previewTimer->setInterval(250);
connect(m_previewTimer, &QTimer::timeout,
this, &DialogAlgoArg::RefreshPreview);
BuildUi();
connect(ui->tabWidget, &QTabWidget::currentChanged, this, [this](int index) {
if (index >= 0 && index < m_visiblePages.size()) {
UpdateTitle(m_visiblePages[index]);
}
UpdatePreviewVisibility();
});
connect(this, &QDialog::finished, this, [this]() {
m_previewTimer->stop();
});
ApplyUiFont();
}
DialogAlgoArg::~DialogAlgoArg()
{
delete ui;
}
void DialogAlgoArg::SetPresenter(ParkingSpaceGuidePresenter* presenter)
{
m_presenter = presenter;
LoadParams();
}
void DialogAlgoArg::SetCurrentPage(ConfigPage page)
{
if (ui && ui->tabWidget) {
ShowTabGroup(page);
}
}
void DialogAlgoArg::ShowTabGroup(ConfigPage page)
{
if (!ui || !ui->tabWidget) {
return;
}
const bool oldBlocked = ui->tabWidget->blockSignals(true);
ui->tabWidget->clear();
HideDetachedTabs();
m_visiblePages.clear();
auto addTab = [this](QWidget* tab, const QString& title, ConfigPage tabPage) {
if (tab) {
ui->tabWidget->addTab(tab, title);
m_visiblePages.push_back(tabPage);
}
};
int selectedIndex = 0;
if (page == ConfigPage::Camera || page == ConfigPage::Lidar) {
addTab(m_cameraTab, QStringLiteral("相机参数"), ConfigPage::Camera);
addTab(m_lidarTab, QStringLiteral("雷达参数"), ConfigPage::Lidar);
selectedIndex = page == ConfigPage::Lidar ? 1 : 0;
} else if (page == ConfigPage::Calibration) {
addTab(m_groundCalibrationTab, QStringLiteral("地面调平"), ConfigPage::Calibration);
} else if (page == ConfigPage::Multicast) {
addTab(m_multicastTab, QStringLiteral("组播参数"), ConfigPage::Multicast);
} else {
addTab(m_planeParkingTab, QStringLiteral("停机几何"), ConfigPage::Detection);
addTab(m_groundCalibrationTab, QStringLiteral("地面调平"), ConfigPage::Detection);
addTab(m_treeGrowTab, QStringLiteral("聚类生长"), ConfigPage::Detection);
addTab(m_guideDecisionTab, QStringLiteral("引导判定"), ConfigPage::Detection);
addTab(m_processTab, QStringLiteral("流程判定"), ConfigPage::Detection);
addTab(m_modelRecognitionTab, QStringLiteral("机型识别"), ConfigPage::Detection);
addTab(m_personDetectionTab, QStringLiteral("人员检测"), ConfigPage::Detection);
}
if (selectedIndex >= 0 && selectedIndex < ui->tabWidget->count()) {
ui->tabWidget->setCurrentIndex(selectedIndex);
}
if (ui->tabWidget->currentWidget()) {
ui->tabWidget->currentWidget()->show();
}
ui->tabWidget->blockSignals(oldBlocked);
UpdateTitle(page);
UpdatePreviewVisibility();
}
void DialogAlgoArg::UpdateTitle(ConfigPage page)
{
QString title = QStringLiteral("停机引导参数设置");
switch (page) {
case ConfigPage::Detection:
title = QStringLiteral("检测参数设置");
break;
case ConfigPage::Camera:
title = QStringLiteral("相机参数设置");
break;
case ConfigPage::Lidar:
title = QStringLiteral("雷达参数设置");
break;
case ConfigPage::Multicast:
title = QStringLiteral("组播参数设置");
break;
case ConfigPage::Calibration:
title = QStringLiteral("雷达地面调平参数");
break;
}
setWindowTitle(title);
if (ui && ui->label_title) {
ui->label_title->setText(title);
}
}
void DialogAlgoArg::HideDetachedTabs()
{
const QList<QWidget*> tabs = {
m_planeParkingTab,
m_groundCalibrationTab,
m_treeGrowTab,
m_guideDecisionTab,
m_processTab,
m_modelRecognitionTab,
m_personDetectionTab,
m_cameraTab,
m_lidarTab,
m_multicastTab
};
for (QWidget* tab : tabs) {
if (tab) {
tab->hide();
}
}
}
void DialogAlgoArg::OnPreviewFrame(const QImage& image)
{
if (image.isNull()) {
return;
}
if (m_roiPreview) {
m_roiPreview->SetImage(image);
}
}
void DialogAlgoArg::UpdatePreviewVisibility()
{
if (!m_roiPreview || !m_previewTimer || !ui || !ui->tabWidget) {
return;
}
const QWidget* currentTab = ui->tabWidget->currentWidget();
const bool showPreview = currentTab == m_modelRecognitionTab ||
currentTab == m_personDetectionTab;
m_roiPreview->setVisible(showPreview);
if (showPreview) {
UpdateRoiPreview();
RefreshPreview();
m_previewTimer->start();
} else {
m_previewTimer->stop();
}
}
void DialogAlgoArg::UpdateRoiPreview()
{
if (!m_roiPreview || !ui || !ui->tabWidget) {
return;
}
const bool modelPreview =
ui->tabWidget->currentWidget() == m_modelRecognitionTab;
const bool personPreview =
ui->tabWidget->currentWidget() == m_personDetectionTab;
if (!modelPreview && !personPreview) {
return;
}
const auto value = [](QLineEdit* edit) {
bool ok = false;
const double result = edit ? edit->text().trimmed().toDouble(&ok) : 0.0;
return ok && std::isfinite(result) ? result : 0.0;
};
const QRectF roi(modelPreview ? value(m_modelRoiX) : value(m_personRoiX),
modelPreview ? value(m_modelRoiY) : value(m_personRoiY),
modelPreview ? value(m_modelRoiWidth) : value(m_personRoiWidth),
modelPreview ? value(m_modelRoiHeight) : value(m_personRoiHeight));
m_roiPreview->SetRoi(roi,
modelPreview
? QStringLiteral("机型识别实时图像")
: QStringLiteral("人员检测实时图像"));
}
void DialogAlgoArg::RefreshPreview()
{
if (!m_presenter || !m_roiPreview || !m_roiPreview->isVisible()) {
return;
}
QImage image;
QString errorMessage;
if (m_presenter->CapturePreviewImage(image, errorMessage) && !image.isNull()) {
m_roiPreview->SetStatus(QString());
OnPreviewFrame(image);
} else {
m_roiPreview->SetStatus(errorMessage.trimmed().isEmpty()
? QStringLiteral("相机图像不可用")
: errorMessage.trimmed());
}
}
void DialogAlgoArg::CalculateGroundCalibration()
{
if (!m_presenter) {
StyledMessageBox::warning(this, QStringLiteral("失败"),
QStringLiteral("系统未初始化"));
return;
}
VrPlaneGroundCalibrationParam calibration;
QString errorMessage;
if (!m_presenter->CalibrateGround(calibration, errorMessage)) {
StyledMessageBox::warning(
this,
QStringLiteral("地面调平失败"),
errorMessage.trimmed().isEmpty()
? QStringLiteral("地面调平算法计算失败")
: errorMessage.trimmed());
return;
}
SetMatrix(m_planeCalib, calibration.planeCalib);
SetDouble(m_planeHeight, calibration.planeHeight);
SetMatrix(m_invRMatrix, calibration.invRMatrix);
StyledMessageBox::information(this, QStringLiteral("地面调平"),
QStringLiteral("算法计算完成,请确认后应用或保存参数"));
}
void DialogAlgoArg::BuildUi()
{
ui->tabWidget->clear();
auto makeTab = [this](QWidget** tabWidget, const QString& title) -> QWidget* {
auto* scroll = new QScrollArea(ui->tabWidget);
scroll->setWidgetResizable(true);
auto* page = new QWidget(scroll);
page->setObjectName(title);
auto* layout = new QFormLayout(page);
layout->setContentsMargins(24, 24, 24, 24);
layout->setSpacing(14);
scroll->setWidget(page);
*tabWidget = scroll;
scroll->hide();
return page;
};
QWidget* planeParking = makeTab(&m_planeParkingTab, QStringLiteral("停机几何"));
m_parkingPointX = AddDoubleEditor(planeParking, QStringLiteral("停机点X(毫米)"), 0, -1000000.0, 1000000.0);
m_parkingPointY = AddDoubleEditor(planeParking, QStringLiteral("停机点Y(毫米)"), 1, -1000000.0, 1000000.0);
m_parkingPointZ = AddDoubleEditor(planeParking, QStringLiteral("停机点Z(毫米)"), 2, -1000000.0, 1000000.0);
m_guideLinePointX = AddDoubleEditor(planeParking, QStringLiteral("引导线远点X(毫米)"), 3, -1000000.0, 1000000.0);
m_guideLinePointY = AddDoubleEditor(planeParking, QStringLiteral("引导线远点Y(毫米)"), 4, -1000000.0, 1000000.0);
m_guideLinePointZ = AddDoubleEditor(planeParking, QStringLiteral("引导线远点Z(毫米)"), 5, -1000000.0, 1000000.0);
m_guidingRange = AddDoubleEditor(planeParking, QStringLiteral("飞机引导范围(毫米)"), 6, 0.0, 10000000.0);
m_parkingRange = AddDoubleEditor(planeParking, QStringLiteral("引导线过滤范围(毫米)"), 7, 0.0, 10000000.0);
m_distFromNoseToWheel = AddDoubleEditor(planeParking, QStringLiteral("机鼻到前轮距离(毫米)"), 8, 0.0, 100000.0);
QWidget* ground = makeTab(&m_groundCalibrationTab, QStringLiteral("地面调平"));
for (int i = 0; i < 9; ++i) {
m_planeCalib[i] = AddDoubleEditor(ground,
QStringLiteral("调平矩阵 R%1%2").arg(i / 3).arg(i % 3), i, -1000.0, 1000.0);
}
m_planeHeight = AddDoubleEditor(ground, QStringLiteral("地面高度(毫米)"), 9, -1000000.0, 1000000.0);
for (int i = 0; i < 9; ++i) {
m_invRMatrix[i] = AddDoubleEditor(ground,
QStringLiteral("逆矩阵 R%1%2").arg(i / 3).arg(i % 3), 10 + i, -1000.0, 1000.0);
}
m_calibrateGroundButton = new QPushButton(QStringLiteral("算法计算地面调平"), ground);
static_cast<QFormLayout*>(ground->layout())->addRow(QString(), m_calibrateGroundButton);
connect(m_calibrateGroundButton, &QPushButton::clicked,
this, &DialogAlgoArg::CalculateGroundCalibration);
QWidget* treeGrow = makeTab(&m_treeGrowTab, QStringLiteral("聚类生长"));
m_yDeviationMax = AddDoubleEditor(treeGrow, QStringLiteral("Y方向最大偏差(毫米)"), 0, 0.0, 1000000.0);
m_zDeviationMax = AddDoubleEditor(treeGrow, QStringLiteral("Z方向最大偏差(毫米)"), 1, 0.0, 1000000.0);
m_maxLineSkipNum = AddIntEditor(treeGrow, QStringLiteral("最大跳线数(-1按距离)"), 2, -1, 1000000);
m_maxSkipDistance = AddDoubleEditor(treeGrow, QStringLiteral("最大跳过距离(毫米,-1禁用)"), 3, -1.0, 1000000.0);
m_minLTypeTreeLen = AddDoubleEditor(treeGrow, QStringLiteral("L型树最小长度(毫米)"), 4, 0.0, 1000000.0);
m_minVTypeTreeLen = AddDoubleEditor(treeGrow, QStringLiteral("V型树最小长度(毫米)"), 5, 0.0, 1000000.0);
QWidget* guideDecision = makeTab(&m_guideDecisionTab, QStringLiteral("引导判定"));
m_lateralTolerance = AddDoubleEditor(guideDecision, QStringLiteral("横向对中容差(毫米)"), 0, 0.0, 100000.0);
m_angleTolerance = AddDoubleEditor(guideDecision, QStringLiteral("航向角容差(度)"), 1, 0.0, 180.0);
QWidget* process = makeTab(&m_processTab, QStringLiteral("流程判定"));
m_dockingStartDistance = AddDoubleEditor(process, QStringLiteral("引导启动距离(毫米)"), 0, 0.0, 1000000.0);
m_captureStartDistance = AddDoubleEditor(process, QStringLiteral("目标捕获距离(毫米)"), 1, 0.0, 1000000.0);
m_approachStartDistance = AddDoubleEditor(process, QStringLiteral("对中/方位引导距离(毫米)"), 2, 0.0, 1000000.0);
m_slowDistance = AddDoubleEditor(process, QStringLiteral("减速触发距离(毫米)"), 3, 0.0, 1000000.0);
m_stopDistanceTolerance = AddDoubleEditor(process, QStringLiteral("到位距离容差(毫米)"), 4, 0.0, 100000.0);
m_overshootDistance = AddDoubleEditor(process, QStringLiteral("越过停止线距离(毫米)"), 5, 0.0, 1000000.0);
m_stoppedShortMinDistance = AddDoubleEditor(process, QStringLiteral("提前停止最小距离(毫米)"), 6, 0.0, 1000000.0);
m_maxApproachSpeed = AddDoubleEditor(process, QStringLiteral("最大接近速度(毫米/秒)"), 7, 0.0, 100000.0);
m_stoppedSpeedThreshold = AddDoubleEditor(process, QStringLiteral("静止速度阈值(毫米/秒)"), 8, 0.0, 100000.0);
m_speedFilterAlpha = AddDoubleEditor(process, QStringLiteral("速度滤波系数"), 9, 0.0, 1.0);
m_distanceChangeThreshold = AddDoubleEditor(process, QStringLiteral("距离变化阈值(毫米)"), 10, 0.0, 1000000.0);
m_lateralOffsetChangeThreshold = AddDoubleEditor(process, QStringLiteral("横向偏移变化阈值(毫米)"), 11, 0.0, 1000000.0);
m_stopStableFrames = AddIntEditor(process, QStringLiteral("到位稳定帧数"), 12, 1, 1000000);
m_stoppedShortStableFrames = AddIntEditor(process, QStringLiteral("提前停止稳定帧数"), 13, 1, 1000000);
m_errorFrameThreshold = AddIntEditor(process, QStringLiteral("连续错误帧阈值"), 14, 1, 1000000);
m_lostFrameThreshold = AddIntEditor(process, QStringLiteral("目标丢失帧阈值"), 15, 1, 1000000);
m_completedHoldFrames = AddIntEditor(process, QStringLiteral("完成状态保持帧数"), 16, 1, 1000000);
QWidget* model = makeTab(&m_modelRecognitionTab, QStringLiteral("机型识别"));
m_modelVerifyDistance = AddDoubleEditor(model, QStringLiteral("机型验证距离(毫米)"), 0, -1000000.0, 1000000.0);
m_modelRoiX = AddDoubleEditor(model, QStringLiteral("飞机检测区域 X (0~1)"), 1, 0.0, 1.0);
m_modelRoiY = AddDoubleEditor(model, QStringLiteral("飞机检测区域 Y (0~1)"), 2, 0.0, 1.0);
m_modelRoiWidth = AddDoubleEditor(model, QStringLiteral("飞机检测区域宽度 (0~1)"), 3, 0.000001, 1.0);
m_modelRoiHeight = AddDoubleEditor(model, QStringLiteral("飞机检测区域高度 (0~1)"), 4, 0.000001, 1.0);
m_confidenceThreshold = AddDoubleEditor(model, QStringLiteral("识别置信度阈值"), 5, 0.0, 1.0);
m_maxRecognitionAttempts = AddIntEditor(model, QStringLiteral("最大识别次数"), 6, 1, 1000);
QWidget* person = makeTab(&m_personDetectionTab, QStringLiteral("人员检测"));
m_personDetectionEnabled = AddCheckBox(person, QStringLiteral("启用停稳后人员检测"), 0);
m_personRoiX = AddDoubleEditor(person, QStringLiteral("轮挡区域 X (0~1)"), 1, 0.0, 1.0);
m_personRoiY = AddDoubleEditor(person, QStringLiteral("轮挡区域 Y (0~1)"), 2, 0.0, 1.0);
m_personRoiWidth = AddDoubleEditor(person, QStringLiteral("轮挡区域宽度 (0~1)"), 3, 0.000001, 1.0);
m_personRoiHeight = AddDoubleEditor(person, QStringLiteral("轮挡区域高度 (0~1)"), 4, 0.000001, 1.0);
m_personConfidenceThreshold = AddDoubleEditor(person, QStringLiteral("人员置信度阈值"), 5, 0.0, 1.0);
m_personStableFrames = AddIntEditor(person, QStringLiteral("连续有效检测次数"), 6, 1, 1000);
m_personDetectionIntervalMs = AddIntEditor(person, QStringLiteral("检测周期(毫秒)"), 7, 10, 60000);
const QList<QLineEdit*> roiEditors = {
m_modelRoiX, m_modelRoiY, m_modelRoiWidth, m_modelRoiHeight,
m_personRoiX, m_personRoiY, m_personRoiWidth, m_personRoiHeight
};
for (QLineEdit* editor : roiEditors) {
connect(editor, &QLineEdit::textChanged,
this, &DialogAlgoArg::UpdateRoiPreview);
}
QWidget* camera = makeTab(&m_cameraTab, QStringLiteral("相机参数"));
m_mvsSerialNumber = AddTextEditor(camera, QStringLiteral("设备序列号"), 0);
m_mvsDeviceIndex = AddIntEditor(camera, QStringLiteral("设备序号"), 1, 0, 64);
m_mvsEnabled = AddCheckBox(camera, QStringLiteral("启用"), 2);
QWidget* lidar = makeTab(&m_lidarTab, QStringLiteral("雷达参数"));
m_lidarType = AddTextEditor(lidar, QStringLiteral("雷达型号"), 0);
m_lidarHost = AddTextEditor(lidar, QStringLiteral("监听地址"), 1);
m_lidarMsopPort = AddIntEditor(lidar, QStringLiteral("数据端口"), 2, 1, 65535);
m_lidarDifopPort = AddIntEditor(lidar, QStringLiteral("设备端口"), 3, 1, 65535);
m_lidarMinDistance = AddDoubleEditor(lidar, QStringLiteral("最小距离(米)"), 4, 0.0, 1000.0);
m_lidarMaxDistance = AddDoubleEditor(lidar, QStringLiteral("最大距离(米)"), 5, 0.0, 1000.0);
m_lidarStartAngle = AddDoubleEditor(lidar, QStringLiteral("起始角度(度)"), 6, 0.0, 360.0);
m_lidarEndAngle = AddDoubleEditor(lidar, QStringLiteral("结束角度(度)"), 7, 0.0, 360.0);
QWidget* udp = makeTab(&m_multicastTab, QStringLiteral("组播参数"));
m_udpAddress = AddTextEditor(udp, QStringLiteral("组播地址"), 0);
m_udpPort = AddIntEditor(udp, QStringLiteral("组播端口"), 1, 1, 65535);
m_udpTargetId = AddTextEditor(udp, QStringLiteral("目标编号"), 2);
m_udpParkId = AddTextEditor(udp, QStringLiteral("车位编号"), 3);
m_udpEnabled = AddCheckBox(udp, QStringLiteral("启用"), 4);
ShowTabGroup(ConfigPage::Detection);
}
void DialogAlgoArg::ApplyUiFont()
{
QFont font;
font.setPointSize(16);
setFont(font);
const QList<QWidget*> widgets = findChildren<QWidget*>();
for (QWidget* widget : widgets) {
widget->setFont(font);
}
}
QLineEdit* DialogAlgoArg::AddDoubleEditor(QWidget* parent, const QString& label, int row, double min, double max)
{
Q_UNUSED(row);
auto* edit = new QLineEdit(parent);
auto* validator = new QDoubleValidator(min, max, 12, edit);
validator->setNotation(QDoubleValidator::ScientificNotation);
edit->setValidator(validator);
static_cast<QFormLayout*>(parent->layout())->addRow(label, edit);
return edit;
}
QLineEdit* DialogAlgoArg::AddIntEditor(QWidget* parent, const QString& label, int row, int min, int max)
{
Q_UNUSED(row);
auto* edit = new QLineEdit(parent);
edit->setValidator(new QIntValidator(min, max, edit));
static_cast<QFormLayout*>(parent->layout())->addRow(label, edit);
return edit;
}
QLineEdit* DialogAlgoArg::AddTextEditor(QWidget* parent, const QString& label, int row, bool password)
{
Q_UNUSED(row);
auto* edit = new QLineEdit(parent);
if (password) {
edit->setEchoMode(QLineEdit::Password);
}
static_cast<QFormLayout*>(parent->layout())->addRow(label, edit);
return edit;
}
QCheckBox* DialogAlgoArg::AddCheckBox(QWidget* parent, const QString& label, int row)
{
Q_UNUSED(row);
auto* check = new QCheckBox(parent);
static_cast<QFormLayout*>(parent->layout())->addRow(label, check);
return check;
}
void DialogAlgoArg::LoadParams()
{
if (!m_presenter || !m_presenter->GetConfigManager()) {
return;
}
const ConfigResult config = m_presenter->GetConfigManager()->GetConfigResult();
const VrAlgorithmParams& params = config.algorithmParams;
const VrPlaneParkingParam& parking = params.planeParkingParam;
SetDouble(m_parkingPointX, parking.parkingPointX);
SetDouble(m_parkingPointY, parking.parkingPointY);
SetDouble(m_parkingPointZ, parking.parkingPointZ);
SetDouble(m_guideLinePointX, parking.guideLinePointX);
SetDouble(m_guideLinePointY, parking.guideLinePointY);
SetDouble(m_guideLinePointZ, parking.guideLinePointZ);
SetDouble(m_guidingRange, parking.guidingRange);
SetDouble(m_parkingRange, parking.parkingRange);
SetDouble(m_distFromNoseToWheel, parking.distFromNoseToWheel);
const VrPlaneGroundCalibrationParam& ground = params.groundCalibrationParam;
SetMatrix(m_planeCalib, ground.planeCalib);
SetDouble(m_planeHeight, ground.planeHeight);
SetMatrix(m_invRMatrix, ground.invRMatrix);
const VrPlaneTreeGrowParam& tree = params.treeGrowParam;
SetDouble(m_yDeviationMax, tree.yDeviationMax);
SetDouble(m_zDeviationMax, tree.zDeviationMax);
SetInt(m_maxLineSkipNum, tree.maxLineSkipNum);
SetDouble(m_maxSkipDistance, tree.maxSkipDistance);
SetDouble(m_minLTypeTreeLen, tree.minLTypeTreeLen);
SetDouble(m_minVTypeTreeLen, tree.minVTypeTreeLen);
const VrGuideDecisionParam& guide = params.guideDecisionParam;
SetDouble(m_lateralTolerance, guide.lateralTolerance);
SetDouble(m_angleTolerance, guide.angleTolerance);
const VrParkingProcessParam& process = params.processParam;
SetDouble(m_dockingStartDistance, process.dockingStartDistance);
SetDouble(m_captureStartDistance, process.captureStartDistance);
SetDouble(m_approachStartDistance, process.approachStartDistance);
SetDouble(m_slowDistance, process.slowDistance);
SetDouble(m_stopDistanceTolerance, process.stopDistanceTolerance);
SetDouble(m_overshootDistance, process.overshootDistance);
SetDouble(m_stoppedShortMinDistance, process.stoppedShortMinDistance);
SetDouble(m_maxApproachSpeed, process.maxApproachSpeed);
SetDouble(m_stoppedSpeedThreshold, process.stoppedSpeedThreshold);
SetDouble(m_speedFilterAlpha, process.speedFilterAlpha);
SetDouble(m_distanceChangeThreshold, process.distanceChangeThreshold);
SetDouble(m_lateralOffsetChangeThreshold, process.lateralOffsetChangeThreshold);
SetInt(m_stopStableFrames, process.stopStableFrames);
SetInt(m_stoppedShortStableFrames, process.stoppedShortStableFrames);
SetInt(m_errorFrameThreshold, process.errorFrameThreshold);
SetInt(m_lostFrameThreshold, process.lostFrameThreshold);
SetInt(m_completedHoldFrames, process.completedHoldFrames);
const VrModelRecognitionParam& model = params.modelRecognitionParam;
SetDouble(m_modelVerifyDistance, model.modelVerifyDistance);
SetDouble(m_modelRoiX, model.roiX);
SetDouble(m_modelRoiY, model.roiY);
SetDouble(m_modelRoiWidth, model.roiWidth);
SetDouble(m_modelRoiHeight, model.roiHeight);
SetDouble(m_confidenceThreshold, model.confidenceThreshold);
SetInt(m_maxRecognitionAttempts, model.maxRecognitionAttempts);
const VrPersonDetectionParam& person = params.personDetectionParam;
m_personDetectionEnabled->setChecked(person.enabled);
SetDouble(m_personRoiX, person.roiX);
SetDouble(m_personRoiY, person.roiY);
SetDouble(m_personRoiWidth, person.roiWidth);
SetDouble(m_personRoiHeight, person.roiHeight);
SetDouble(m_personConfidenceThreshold, person.confidenceThreshold);
SetInt(m_personStableFrames, person.stableFrames);
SetInt(m_personDetectionIntervalMs, person.detectionIntervalMs);
m_mvsSerialNumber->setText(QString::fromStdString(config.mvsCamera.serialNumber));
SetInt(m_mvsDeviceIndex, config.mvsCamera.deviceIndex);
m_mvsEnabled->setChecked(config.mvsCamera.enabled);
m_lidarType->setText(QString::fromStdString(config.lidarConfig.lidarType));
m_lidarHost->setText(QString::fromStdString(config.lidarConfig.hostAddress));
SetInt(m_lidarMsopPort, config.lidarConfig.msopPort);
SetInt(m_lidarDifopPort, config.lidarConfig.difopPort);
SetDouble(m_lidarMinDistance, config.lidarConfig.minDistance);
SetDouble(m_lidarMaxDistance, config.lidarConfig.maxDistance);
SetDouble(m_lidarStartAngle, config.lidarConfig.startAngle);
SetDouble(m_lidarEndAngle, config.lidarConfig.endAngle);
m_udpAddress->setText(QString::fromStdString(config.udpBroadcastConfig.address));
SetInt(m_udpPort, config.udpBroadcastConfig.port);
m_udpTargetId->setText(QString::fromStdString(config.udpBroadcastConfig.targetId));
m_udpParkId->setText(QString::fromStdString(config.udpBroadcastConfig.parkId));
m_udpEnabled->setChecked(config.udpBroadcastConfig.enabled);
}
bool DialogAlgoArg::SaveParams()
{
if (!m_presenter || !m_presenter->GetConfigManager()) {
return false;
}
SystemConfig systemConfig = m_presenter->GetConfigManager()->GetConfig();
ConfigResult& config = systemConfig.configResult;
VrAlgorithmParams& params = config.algorithmParams;
VrPlaneParkingParam& parking = params.planeParkingParam;
if (!GetDouble(m_parkingPointX, QStringLiteral("停机点X"), parking.parkingPointX)) return false;
if (!GetDouble(m_parkingPointY, QStringLiteral("停机点Y"), parking.parkingPointY)) return false;
if (!GetDouble(m_parkingPointZ, QStringLiteral("停机点Z"), parking.parkingPointZ)) return false;
if (!GetDouble(m_guideLinePointX, QStringLiteral("引导线远点X"), parking.guideLinePointX)) return false;
if (!GetDouble(m_guideLinePointY, QStringLiteral("引导线远点Y"), parking.guideLinePointY)) return false;
if (!GetDouble(m_guideLinePointZ, QStringLiteral("引导线远点Z"), parking.guideLinePointZ)) return false;
if (!GetDouble(m_guidingRange, QStringLiteral("飞机引导范围"), parking.guidingRange)) return false;
if (!GetDouble(m_parkingRange, QStringLiteral("引导线过滤范围"), parking.parkingRange)) return false;
if (!GetDouble(m_distFromNoseToWheel, QStringLiteral("机鼻到前轮距离"), parking.distFromNoseToWheel)) return false;
const double dx = parking.guideLinePointX - parking.parkingPointX;
const double dy = parking.guideLinePointY - parking.parkingPointY;
const double dz = parking.guideLinePointZ - parking.parkingPointZ;
if (parking.guidingRange <= 0.0 || parking.parkingRange <= 0.0 ||
std::sqrt(dx * dx + dy * dy + dz * dz) < 20000.0) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"),
QStringLiteral("引导范围必须大于0且引导线远点距离停机点至少20米"));
return false;
}
VrPlaneGroundCalibrationParam& ground = params.groundCalibrationParam;
if (!GetMatrix(m_planeCalib, QStringLiteral("调平矩阵"), ground.planeCalib)) return false;
if (!GetDouble(m_planeHeight, QStringLiteral("地面高度"), ground.planeHeight)) return false;
if (!GetMatrix(m_invRMatrix, QStringLiteral("逆矩阵"), ground.invRMatrix)) return false;
VrPlaneTreeGrowParam& tree = params.treeGrowParam;
if (!GetDouble(m_yDeviationMax, QStringLiteral("Y方向最大偏差"), tree.yDeviationMax)) return false;
if (!GetDouble(m_zDeviationMax, QStringLiteral("Z方向最大偏差"), tree.zDeviationMax)) return false;
if (!GetInt(m_maxLineSkipNum, QStringLiteral("最大跳线数"), tree.maxLineSkipNum)) return false;
if (!GetDouble(m_maxSkipDistance, QStringLiteral("最大跳过距离"), tree.maxSkipDistance)) return false;
if (!GetDouble(m_minLTypeTreeLen, QStringLiteral("L型树最小长度"), tree.minLTypeTreeLen)) return false;
if (!GetDouble(m_minVTypeTreeLen, QStringLiteral("V型树最小长度"), tree.minVTypeTreeLen)) return false;
if (tree.yDeviationMax <= 0.0 || tree.zDeviationMax <= 0.0 ||
(tree.maxLineSkipNum == -1 && tree.maxSkipDistance < 0.0)) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"), QStringLiteral("聚类生长参数组合无效"));
return false;
}
VrGuideDecisionParam& guide = params.guideDecisionParam;
if (!GetDouble(m_lateralTolerance, QStringLiteral("横向对中容差"), guide.lateralTolerance)) return false;
if (!GetDouble(m_angleTolerance, QStringLiteral("航向角容差"), guide.angleTolerance)) return false;
VrParkingProcessParam& process = params.processParam;
if (!GetDouble(m_dockingStartDistance, QStringLiteral("引导启动距离"), process.dockingStartDistance)) return false;
if (!GetDouble(m_captureStartDistance, QStringLiteral("目标捕获距离"), process.captureStartDistance)) return false;
if (!GetDouble(m_approachStartDistance, QStringLiteral("对中/方位引导距离"), process.approachStartDistance)) return false;
if (!GetDouble(m_slowDistance, QStringLiteral("减速触发距离"), process.slowDistance)) return false;
if (!GetDouble(m_stopDistanceTolerance, QStringLiteral("到位距离容差"), process.stopDistanceTolerance)) return false;
if (!GetDouble(m_overshootDistance, QStringLiteral("越过停止线距离"), process.overshootDistance)) return false;
if (!GetDouble(m_stoppedShortMinDistance, QStringLiteral("提前停止最小距离"), process.stoppedShortMinDistance)) return false;
if (!GetDouble(m_maxApproachSpeed, QStringLiteral("最大接近速度"), process.maxApproachSpeed)) return false;
if (!GetDouble(m_stoppedSpeedThreshold, QStringLiteral("静止速度阈值"), process.stoppedSpeedThreshold)) return false;
if (!GetDouble(m_speedFilterAlpha, QStringLiteral("速度滤波系数"), process.speedFilterAlpha)) return false;
if (!GetDouble(m_distanceChangeThreshold, QStringLiteral("距离变化阈值"), process.distanceChangeThreshold)) return false;
if (!GetDouble(m_lateralOffsetChangeThreshold, QStringLiteral("横向偏移变化阈值"), process.lateralOffsetChangeThreshold)) return false;
if (!GetInt(m_stopStableFrames, QStringLiteral("到位稳定帧数"), process.stopStableFrames)) return false;
if (!GetInt(m_stoppedShortStableFrames, QStringLiteral("提前停止稳定帧数"), process.stoppedShortStableFrames)) return false;
if (!GetInt(m_errorFrameThreshold, QStringLiteral("连续错误帧阈值"), process.errorFrameThreshold)) return false;
if (!GetInt(m_lostFrameThreshold, QStringLiteral("目标丢失帧阈值"), process.lostFrameThreshold)) return false;
if (!GetInt(m_completedHoldFrames, QStringLiteral("完成状态保持帧数"), process.completedHoldFrames)) return false;
if (process.dockingStartDistance <= process.captureStartDistance ||
process.captureStartDistance <= process.approachStartDistance ||
process.approachStartDistance <= process.slowDistance ||
process.slowDistance <= process.stopDistanceTolerance ||
process.overshootDistance < process.stopDistanceTolerance ||
process.stoppedShortMinDistance < process.stopDistanceTolerance ||
process.maxApproachSpeed <= process.stoppedSpeedThreshold) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"),
QStringLiteral("流程距离应满足启动>捕获>对中/方位>减速>到位容差,越线和提前停止距离不得小于到位容差,最大接近速度必须大于静止速度阈值"));
return false;
}
VrModelRecognitionParam& model = params.modelRecognitionParam;
if (!GetDouble(m_modelVerifyDistance, QStringLiteral("机型验证距离"), model.modelVerifyDistance)) return false;
if (!GetDouble(m_modelRoiX, QStringLiteral("飞机检测区域 X"), model.roiX)) return false;
if (!GetDouble(m_modelRoiY, QStringLiteral("飞机检测区域 Y"), model.roiY)) return false;
if (!GetDouble(m_modelRoiWidth, QStringLiteral("飞机检测区域宽度"), model.roiWidth)) return false;
if (!GetDouble(m_modelRoiHeight, QStringLiteral("飞机检测区域高度"), model.roiHeight)) return false;
if (!GetDouble(m_confidenceThreshold, QStringLiteral("识别置信度阈值"), model.confidenceThreshold)) return false;
if (!GetInt(m_maxRecognitionAttempts, QStringLiteral("最大识别次数"), model.maxRecognitionAttempts)) return false;
if (model.roiX + model.roiWidth > 1.0 ||
model.roiY + model.roiHeight > 1.0) {
StyledMessageBox::warning(this,
QStringLiteral("参数错误"),
QStringLiteral("飞机检测区域必须完整位于归一化图像范围 0~1 内"));
return false;
}
VrPersonDetectionParam& person = params.personDetectionParam;
person.enabled = m_personDetectionEnabled->isChecked();
if (!GetDouble(m_personRoiX, QStringLiteral("轮挡区域 X"), person.roiX)) return false;
if (!GetDouble(m_personRoiY, QStringLiteral("轮挡区域 Y"), person.roiY)) return false;
if (!GetDouble(m_personRoiWidth, QStringLiteral("轮挡区域宽度"), person.roiWidth)) return false;
if (!GetDouble(m_personRoiHeight, QStringLiteral("轮挡区域高度"), person.roiHeight)) return false;
if (!GetDouble(m_personConfidenceThreshold, QStringLiteral("人员置信度阈值"), person.confidenceThreshold)) return false;
if (!GetInt(m_personStableFrames, QStringLiteral("连续有效检测次数"), person.stableFrames)) return false;
if (!GetInt(m_personDetectionIntervalMs, QStringLiteral("人员检测周期"), person.detectionIntervalMs)) return false;
if (person.roiX + person.roiWidth > 1.0 ||
person.roiY + person.roiHeight > 1.0) {
StyledMessageBox::warning(this,
QStringLiteral("参数错误"),
QStringLiteral("轮挡区域必须完整位于归一化图像范围 0~1 内"));
return false;
}
config.mvsCamera.serialNumber = m_mvsSerialNumber->text().trimmed().toStdString();
if (!GetInt(m_mvsDeviceIndex, QStringLiteral("相机设备序号"), config.mvsCamera.deviceIndex)) return false;
config.mvsCamera.enabled = m_mvsEnabled->isChecked();
config.lidarConfig.lidarType = m_lidarType->text().trimmed().toStdString();
config.lidarConfig.hostAddress = m_lidarHost->text().trimmed().toStdString();
int intValue = 0;
if (!GetInt(m_lidarMsopPort, QStringLiteral("雷达数据端口"), intValue)) return false;
config.lidarConfig.msopPort = static_cast<unsigned short>(intValue);
if (!GetInt(m_lidarDifopPort, QStringLiteral("雷达设备端口"), intValue)) return false;
config.lidarConfig.difopPort = static_cast<unsigned short>(intValue);
if (!GetFloat(m_lidarMinDistance, QStringLiteral("雷达最小距离"), config.lidarConfig.minDistance)) return false;
if (!GetFloat(m_lidarMaxDistance, QStringLiteral("雷达最大距离"), config.lidarConfig.maxDistance)) return false;
if (!GetFloat(m_lidarStartAngle, QStringLiteral("雷达起始角度"), config.lidarConfig.startAngle)) return false;
if (!GetFloat(m_lidarEndAngle, QStringLiteral("雷达结束角度"), config.lidarConfig.endAngle)) return false;
config.udpBroadcastConfig.address = m_udpAddress->text().trimmed().toStdString();
if (!GetInt(m_udpPort, QStringLiteral("组播端口"), config.udpBroadcastConfig.port)) return false;
config.udpBroadcastConfig.targetId = m_udpTargetId->text().trimmed().toStdString();
config.udpBroadcastConfig.parkId = m_udpParkId->text().trimmed().toStdString();
config.udpBroadcastConfig.enabled = m_udpEnabled->isChecked();
config.Normalize();
if (!m_presenter->GetConfigManager()->UpdateFullConfig(systemConfig)) {
StyledMessageBox::warning(this, QStringLiteral("失败"), QStringLiteral("更新配置缓存失败"));
return false;
}
const QString configPath = PathManager::GetInstance().GetConfigFilePath();
if (!m_presenter->GetConfigManager()->SaveConfigToFile(configPath.toStdString())) {
StyledMessageBox::warning(this, QStringLiteral("失败"), QStringLiteral("保存配置文件失败"));
return false;
}
m_presenter->OnConfigChanged(config);
return true;
}
void DialogAlgoArg::ResetParams()
{
ConfigResult config;
config.Normalize();
const VrAlgorithmParams& params = config.algorithmParams;
const VrPlaneParkingParam& parking = params.planeParkingParam;
SetDouble(m_parkingPointX, parking.parkingPointX);
SetDouble(m_parkingPointY, parking.parkingPointY);
SetDouble(m_parkingPointZ, parking.parkingPointZ);
SetDouble(m_guideLinePointX, parking.guideLinePointX);
SetDouble(m_guideLinePointY, parking.guideLinePointY);
SetDouble(m_guideLinePointZ, parking.guideLinePointZ);
SetDouble(m_guidingRange, parking.guidingRange);
SetDouble(m_parkingRange, parking.parkingRange);
SetDouble(m_distFromNoseToWheel, parking.distFromNoseToWheel);
const VrPlaneGroundCalibrationParam& ground = params.groundCalibrationParam;
SetMatrix(m_planeCalib, ground.planeCalib);
SetDouble(m_planeHeight, ground.planeHeight);
SetMatrix(m_invRMatrix, ground.invRMatrix);
const VrPlaneTreeGrowParam& tree = params.treeGrowParam;
SetDouble(m_yDeviationMax, tree.yDeviationMax);
SetDouble(m_zDeviationMax, tree.zDeviationMax);
SetInt(m_maxLineSkipNum, tree.maxLineSkipNum);
SetDouble(m_maxSkipDistance, tree.maxSkipDistance);
SetDouble(m_minLTypeTreeLen, tree.minLTypeTreeLen);
SetDouble(m_minVTypeTreeLen, tree.minVTypeTreeLen);
const VrGuideDecisionParam& guide = params.guideDecisionParam;
SetDouble(m_lateralTolerance, guide.lateralTolerance);
SetDouble(m_angleTolerance, guide.angleTolerance);
const VrParkingProcessParam& process = params.processParam;
SetDouble(m_dockingStartDistance, process.dockingStartDistance);
SetDouble(m_captureStartDistance, process.captureStartDistance);
SetDouble(m_approachStartDistance, process.approachStartDistance);
SetDouble(m_slowDistance, process.slowDistance);
SetDouble(m_stopDistanceTolerance, process.stopDistanceTolerance);
SetDouble(m_overshootDistance, process.overshootDistance);
SetDouble(m_stoppedShortMinDistance, process.stoppedShortMinDistance);
SetDouble(m_maxApproachSpeed, process.maxApproachSpeed);
SetDouble(m_stoppedSpeedThreshold, process.stoppedSpeedThreshold);
SetDouble(m_speedFilterAlpha, process.speedFilterAlpha);
SetDouble(m_distanceChangeThreshold, process.distanceChangeThreshold);
SetDouble(m_lateralOffsetChangeThreshold, process.lateralOffsetChangeThreshold);
SetInt(m_stopStableFrames, process.stopStableFrames);
SetInt(m_stoppedShortStableFrames, process.stoppedShortStableFrames);
SetInt(m_errorFrameThreshold, process.errorFrameThreshold);
SetInt(m_lostFrameThreshold, process.lostFrameThreshold);
SetInt(m_completedHoldFrames, process.completedHoldFrames);
const VrModelRecognitionParam& model = params.modelRecognitionParam;
SetDouble(m_modelVerifyDistance, model.modelVerifyDistance);
SetDouble(m_modelRoiX, model.roiX);
SetDouble(m_modelRoiY, model.roiY);
SetDouble(m_modelRoiWidth, model.roiWidth);
SetDouble(m_modelRoiHeight, model.roiHeight);
SetDouble(m_confidenceThreshold, model.confidenceThreshold);
SetInt(m_maxRecognitionAttempts, model.maxRecognitionAttempts);
const VrPersonDetectionParam& person = params.personDetectionParam;
m_personDetectionEnabled->setChecked(person.enabled);
SetDouble(m_personRoiX, person.roiX);
SetDouble(m_personRoiY, person.roiY);
SetDouble(m_personRoiWidth, person.roiWidth);
SetDouble(m_personRoiHeight, person.roiHeight);
SetDouble(m_personConfidenceThreshold, person.confidenceThreshold);
SetInt(m_personStableFrames, person.stableFrames);
SetInt(m_personDetectionIntervalMs, person.detectionIntervalMs);
m_mvsSerialNumber->setText(QString::fromStdString(config.mvsCamera.serialNumber));
SetInt(m_mvsDeviceIndex, config.mvsCamera.deviceIndex);
m_mvsEnabled->setChecked(config.mvsCamera.enabled);
m_lidarType->setText(QString::fromStdString(config.lidarConfig.lidarType));
m_lidarHost->setText(QString::fromStdString(config.lidarConfig.hostAddress));
SetInt(m_lidarMsopPort, config.lidarConfig.msopPort);
SetInt(m_lidarDifopPort, config.lidarConfig.difopPort);
SetDouble(m_lidarMinDistance, config.lidarConfig.minDistance);
SetDouble(m_lidarMaxDistance, config.lidarConfig.maxDistance);
SetDouble(m_lidarStartAngle, config.lidarConfig.startAngle);
SetDouble(m_lidarEndAngle, config.lidarConfig.endAngle);
m_udpAddress->setText(QString::fromStdString(config.udpBroadcastConfig.address));
SetInt(m_udpPort, config.udpBroadcastConfig.port);
m_udpTargetId->setText(QString::fromStdString(config.udpBroadcastConfig.targetId));
m_udpParkId->setText(QString::fromStdString(config.udpBroadcastConfig.parkId));
m_udpEnabled->setChecked(config.udpBroadcastConfig.enabled);
}
void DialogAlgoArg::SetDouble(QLineEdit* edit, double value)
{
if (edit) edit->setText(QString::number(value, 'g', 12));
}
void DialogAlgoArg::SetInt(QLineEdit* edit, int value)
{
if (edit) edit->setText(QString::number(value));
}
bool DialogAlgoArg::GetDouble(QLineEdit* edit, const QString& label, double& value)
{
bool ok = false;
value = edit ? edit->text().trimmed().toDouble(&ok) : 0.0;
if (!edit || !edit->hasAcceptableInput() || !ok || !std::isfinite(value)) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"), QStringLiteral("%1无效").arg(label));
if (edit) edit->setFocus();
return false;
}
return true;
}
bool DialogAlgoArg::GetFloat(QLineEdit* edit, const QString& label, float& value)
{
double doubleValue = 0.0;
if (!GetDouble(edit, label, doubleValue)) return false;
value = static_cast<float>(doubleValue);
return true;
}
bool DialogAlgoArg::GetInt(QLineEdit* edit, const QString& label, int& value)
{
bool ok = false;
value = edit ? edit->text().trimmed().toInt(&ok) : 0;
if (!edit || !edit->hasAcceptableInput() || !ok) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"), QStringLiteral("%1无效").arg(label));
if (edit) edit->setFocus();
return false;
}
return true;
}
void DialogAlgoArg::SetMatrix(QLineEdit* const edits[9], const double values[9])
{
for (int i = 0; i < 9; ++i) SetDouble(edits[i], values[i]);
}
bool DialogAlgoArg::GetMatrix(QLineEdit* const edits[9], const QString& label, double values[9])
{
for (int i = 0; i < 9; ++i) {
if (!GetDouble(edits[i], QStringLiteral("%1 R%2%3").arg(label).arg(i / 3).arg(i % 3), values[i])) {
return false;
}
}
return true;
}
void DialogAlgoArg::on_btnOK_clicked()
{
if (SaveParams()) accept();
}
void DialogAlgoArg::on_btnCancel_clicked()
{
reject();
}
void DialogAlgoArg::on_btnApply_clicked()
{
if (SaveParams()) {
StyledMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("参数已应用"));
}
}
void DialogAlgoArg::on_btnReset_clicked()
{
ResetParams();
}