374 lines
15 KiB
C++
374 lines
15 KiB
C++
#include "dialogalgoarg.h"
|
||
#include "ui_dialogalgoarg.h"
|
||
#include <QMessageBox>
|
||
#include <QPushButton>
|
||
#include <QtCore/QCoreApplication>
|
||
#include <QtCore/QFileInfo>
|
||
#include <QtCore/QDir>
|
||
#include <QtCore/QStandardPaths>
|
||
#include <QtCore/QFile>
|
||
#include <QJsonDocument>
|
||
#include <QJsonObject>
|
||
#include <QVariant>
|
||
#include <QDoubleValidator>
|
||
#include <QIntValidator>
|
||
#include <QLocale>
|
||
#include "PathManager.h"
|
||
#include "StyledMessageBox.h"
|
||
#include <algorithm>
|
||
|
||
#include "VrLog.h"
|
||
|
||
DialogAlgoarg::DialogAlgoarg(IVrBeltTearingConfig* beltTearingConfig, const QMap<QString, ServerInfo>& serverInfos, QWidget *parent)
|
||
: QDialog(parent)
|
||
, ui(new Ui::DialogAlgoarg)
|
||
, m_beltTearingConfig(beltTearingConfig)
|
||
, m_serverInfos(serverInfos)
|
||
{
|
||
ui->setupUi(this);
|
||
|
||
auto setNonNegativeValidator = [this](QLineEdit* edit) {
|
||
QDoubleValidator* validator = new QDoubleValidator(0.0, 1000000.0, 3, edit);
|
||
validator->setNotation(QDoubleValidator::StandardNotation);
|
||
QLocale locale = QLocale::c();
|
||
locale.setNumberOptions(QLocale::RejectGroupSeparator);
|
||
validator->setLocale(locale);
|
||
edit->setValidator(validator);
|
||
};
|
||
|
||
auto setPositiveIntegerValidator = [](QLineEdit* edit) {
|
||
edit->setValidator(new QIntValidator(1, 1000000, edit));
|
||
};
|
||
setNonNegativeValidator(ui->lineEdit_tearingMinDepth);
|
||
setNonNegativeValidator(ui->lineEdit_tearingMinYWidth);
|
||
setNonNegativeValidator(ui->lineEdit_tearingMaxYWidth);
|
||
setPositiveIntegerValidator(ui->lineEdit_maxQueueSize);
|
||
setPositiveIntegerValidator(ui->lineEdit_generationInterval);
|
||
setPositiveIntegerValidator(ui->lineEdit_imageLineCount);
|
||
setPositiveIntegerValidator(ui->lineEdit_pointCloudLineStep);
|
||
setPositiveIntegerValidator(ui->lineEdit_pointCloudPointStep);
|
||
|
||
// 隐藏标题栏
|
||
// setWindowFlags(Qt::FramelessWindowHint);
|
||
|
||
// 设置服务器选择组合框
|
||
setupServerComboBox();
|
||
|
||
// 连接服务器选择变化信号
|
||
connect(ui->comboBox_serverSelect, &QComboBox::currentTextChanged, this, &DialogAlgoarg::on_serverComboBox_currentTextChanged);
|
||
}
|
||
|
||
DialogAlgoarg::~DialogAlgoarg()
|
||
{
|
||
delete ui;
|
||
}
|
||
|
||
void DialogAlgoarg::Init()
|
||
{
|
||
requestParamFromServer();
|
||
}
|
||
|
||
void DialogAlgoarg::updateServerInfos(const QMap<QString, ServerInfo>& serverInfos)
|
||
{
|
||
// 保存当前选择的服务器名称
|
||
QString currentServerName;
|
||
int currentIndex = ui->comboBox_serverSelect->currentIndex();
|
||
if (currentIndex >= 0 && currentIndex < m_serverInfos.size()) {
|
||
auto it = m_serverInfos.begin();
|
||
std::advance(it, currentIndex);
|
||
currentServerName = QString::fromStdString(it.value().name);
|
||
}
|
||
|
||
// 更新服务器列表
|
||
m_serverInfos = serverInfos;
|
||
|
||
// 重新设置组合框
|
||
setupServerComboBox();
|
||
|
||
// 尝试恢复之前的选择
|
||
if (!currentServerName.isEmpty()) {
|
||
for (int i = 0; i < ui->comboBox_serverSelect->count(); ++i) {
|
||
if (ui->comboBox_serverSelect->itemText(i) == currentServerName) {
|
||
ui->comboBox_serverSelect->setCurrentIndex(i);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
LOG_DEBUG("DialogAlgoarg: Server list updated, now has %d servers\n", m_serverInfos.size());
|
||
}
|
||
|
||
void DialogAlgoarg::setupServerComboBox()
|
||
{
|
||
ui->comboBox_serverSelect->clear();
|
||
|
||
int index = 0;
|
||
for (auto it = m_serverInfos.begin(); it != m_serverInfos.end(); ++it) {
|
||
// 使用 ServerInfo 的 name 字段作为显示文本
|
||
QString displayName = QString::fromStdString(it.value().name);
|
||
// 存储索引作为用户数据
|
||
ui->comboBox_serverSelect->addItem(displayName, QVariant(index));
|
||
index++;
|
||
}
|
||
}
|
||
|
||
void DialogAlgoarg::requestParamFromServer()
|
||
{
|
||
ui->label_version->setText(tr("软件版本: 未读取"));
|
||
ui->label_algorithmVersion->setText(tr("算法版本: 未读取"));
|
||
// 获取当前选择的服务器索引
|
||
int selectedIndex = ui->comboBox_serverSelect->currentData().toInt();
|
||
|
||
if (selectedIndex < 0 || selectedIndex >= m_serverInfos.size()) {
|
||
return;
|
||
}
|
||
|
||
// 根据索引获取对应的服务器名称
|
||
auto it = m_serverInfos.begin();
|
||
std::advance(it, selectedIndex);
|
||
QString selectedServer = it.key();
|
||
|
||
LOG_DEBUG("request param from : %s \n", selectedServer.toStdString().c_str());
|
||
|
||
// 同时从服务器加载数据
|
||
emit requestServerData(selectedServer);
|
||
}
|
||
|
||
void DialogAlgoarg::on_serverComboBox_currentTextChanged(const QString &text)
|
||
{
|
||
requestParamFromServer();
|
||
}
|
||
|
||
bool DialogAlgoarg::sendParametersToServer()
|
||
{
|
||
// 获取当前选择的服务器索引
|
||
int selectedIndex = ui->comboBox_serverSelect->currentData().toInt();
|
||
if (selectedIndex < 0 || selectedIndex >= m_serverInfos.size()) {
|
||
return false;
|
||
}
|
||
|
||
if (!ui->lineEdit_tearingMinDepth->hasAcceptableInput() ||
|
||
!ui->lineEdit_tearingMinYWidth->hasAcceptableInput() ||
|
||
!ui->lineEdit_tearingMaxYWidth->hasAcceptableInput()) {
|
||
StyledMessageBox::warning(this, tr("参数错误"), tr("请输入有效的最小撕裂深度、最小撕裂宽度和最大撕裂宽度。"));
|
||
return false;
|
||
}
|
||
const double minWidth = ui->lineEdit_tearingMinYWidth->text().toDouble();
|
||
const double maxWidth = ui->lineEdit_tearingMaxYWidth->text().toDouble();
|
||
if (maxWidth <= 0.0 || maxWidth < minWidth) {
|
||
StyledMessageBox::warning(this, tr("参数错误"), tr("最大撕裂宽度必须大于0,且不能小于最小撕裂宽度。"));
|
||
return false;
|
||
}
|
||
|
||
// 根据索引获取对应的服务器名称
|
||
auto it = m_serverInfos.begin();
|
||
std::advance(it, selectedIndex);
|
||
QString selectedServer = it.key();
|
||
|
||
// 创建JSON格式的参数数据
|
||
QJsonObject paramJson;
|
||
paramJson["command"] = "setAlgorithmParams";
|
||
paramJson["scanXScale"] = ui->lineEdit_scanXScale->text().toDouble();
|
||
paramJson["scanYScale"] = ui->lineEdit_scanYScale->text().toDouble();
|
||
paramJson["differnceBinTh"] = ui->lineEdit_differnceBinTh->text().toDouble();
|
||
|
||
paramJson["tearingMinLen"] = ui->lineEdit_tearingMinLen->text().toDouble();
|
||
paramJson["tearingMinGap"] = ui->lineEdit_tearingMinGap->text().toDouble();
|
||
paramJson["tearingMinDepth"] = ui->lineEdit_tearingMinDepth->text().toDouble();
|
||
paramJson["tearingMinYWidth"] = minWidth;
|
||
paramJson["tearingMaxYWidth"] = maxWidth;
|
||
|
||
paramJson["sameGapTh"] = ui->lineEdit_sameGapTh->text().toDouble();
|
||
paramJson["gapChkWin"] = ui->lineEdit_gapChkWin->text().toInt();
|
||
|
||
// 添加相机IP配置
|
||
paramJson["cameraIP"] = ui->lineEdit_cameraIP->text();
|
||
|
||
// 添加队列处理参数
|
||
paramJson["maxQueueSize"] = ui->lineEdit_maxQueueSize->text().toInt();
|
||
paramJson["generationInterval"] = ui->lineEdit_generationInterval->text().toInt();
|
||
paramJson["imageLineCount"] = ui->lineEdit_imageLineCount->text().toInt();
|
||
paramJson["pointCloudEnabled"] = ui->checkBox_pointCloudEnabled->isChecked();
|
||
paramJson["pointCloudLineStep"] = ui->lineEdit_pointCloudLineStep->text().toInt();
|
||
paramJson["pointCloudPointStep"] = ui->lineEdit_pointCloudPointStep->text().toInt();
|
||
|
||
QJsonDocument doc(paramJson);
|
||
QByteArray data = doc.toJson();
|
||
|
||
// 这里需要通过网络发送给对应的服务器
|
||
// 具体实现将在Presenter中完成
|
||
emit parametersChanged(selectedServer, data);
|
||
return true;
|
||
}
|
||
|
||
void DialogAlgoarg::onServerDataReceived(const QString& serverName, const QJsonObject& data)
|
||
{
|
||
const int selectedIndex = ui->comboBox_serverSelect->currentData().toInt();
|
||
if (selectedIndex < 0 || selectedIndex >= m_serverInfos.size()) {
|
||
return;
|
||
}
|
||
auto selectedServer = m_serverInfos.cbegin();
|
||
std::advance(selectedServer, selectedIndex);
|
||
if (selectedServer.key() != serverName) {
|
||
return;
|
||
}
|
||
// 更新UI显示从服务器获取的参数
|
||
updateUIWithServerData(data);
|
||
|
||
// StyledMessageBox::information(this, "提示", "从服务器加载算法参数完成!");
|
||
}
|
||
|
||
void DialogAlgoarg::updateUIWithServerData(const QJsonObject& serverData)
|
||
{
|
||
// 从服务器返回的数据中提取算法参数并更新UI
|
||
// 检查数据是否是配置响应格式
|
||
QJsonObject algorithmParams;
|
||
if (serverData.contains("config") && serverData["config"].isObject()) {
|
||
// 从 config 字段中提取算法参数(服务器返回的配置响应格式)
|
||
QJsonObject configObj = serverData["config"].toObject();
|
||
if (configObj.contains("algorithmParams") && configObj["algorithmParams"].isObject()) {
|
||
algorithmParams = configObj["algorithmParams"].toObject();
|
||
}
|
||
} else if (serverData.contains("algorithmParams") && serverData["algorithmParams"].isObject()) {
|
||
// 直接从根字段提取算法参数(旧格式或其他响应格式)
|
||
algorithmParams = serverData["algorithmParams"].toObject();
|
||
}
|
||
|
||
// 显示版本信息(如果存在)
|
||
if (serverData.contains("version")) {
|
||
QString version = serverData["version"].toString();
|
||
// 在UI上显示版本信息
|
||
ui->label_version->setText(tr("软件版本: %1").arg(version));
|
||
}
|
||
|
||
const QJsonObject config = serverData.value("config").toObject();
|
||
const QString algorithmVersion = serverData.value("algorithmVersion").toString(
|
||
config.value("algorithmVersion").toString());
|
||
ui->label_algorithmVersion->setText(tr("算法版本: %1").arg(
|
||
algorithmVersion.isEmpty() ? tr("未提供") : algorithmVersion));
|
||
|
||
const BeltTearingParam defaults;
|
||
ui->lineEdit_tearingMinDepth->setText(QString::number(
|
||
algorithmParams.value("tearingMinDepth").toDouble(defaults.tearingMinDepth)));
|
||
ui->lineEdit_tearingMinYWidth->setText(QString::number(
|
||
algorithmParams.value("tearingMinYWidth").toDouble(defaults.tearingMinYWidth)));
|
||
ui->lineEdit_tearingMaxYWidth->setText(QString::number(
|
||
algorithmParams.value("tearingMaxYWidth").toDouble(defaults.tearingMaxYWidth)));
|
||
|
||
// 更新算法参数UI
|
||
if (!algorithmParams.isEmpty()) {
|
||
if (algorithmParams.contains("scanXScale")) {
|
||
ui->lineEdit_scanXScale->setText(QString::number(algorithmParams["scanXScale"].toDouble()));
|
||
}
|
||
|
||
if (algorithmParams.contains("scanYScale")) {
|
||
ui->lineEdit_scanYScale->setText(QString::number(algorithmParams["scanYScale"].toDouble()));
|
||
}
|
||
|
||
if (algorithmParams.contains("differnceBinTh")) {
|
||
ui->lineEdit_differnceBinTh->setText(QString::number(algorithmParams["differnceBinTh"].toDouble()));
|
||
}
|
||
|
||
if (algorithmParams.contains("tearingMinLen")) {
|
||
ui->lineEdit_tearingMinLen->setText(QString::number(algorithmParams["tearingMinLen"].toDouble()));
|
||
}
|
||
|
||
// 处理额外的参数
|
||
if (algorithmParams.contains("tearingMinGap")) {
|
||
ui->lineEdit_tearingMinGap->setText(QString::number(algorithmParams["tearingMinGap"].toDouble()));
|
||
}
|
||
|
||
if (algorithmParams.contains("sameGapTh")) {
|
||
ui->lineEdit_sameGapTh->setText(QString::number(algorithmParams["sameGapTh"].toDouble()));
|
||
}
|
||
|
||
if (algorithmParams.contains("gapChkWin")) {
|
||
ui->lineEdit_gapChkWin->setText(QString::number(algorithmParams["gapChkWin"].toInt()));
|
||
}
|
||
}
|
||
|
||
// 更新相机IP配置
|
||
QJsonObject cameraConfig;
|
||
if (serverData.contains("config") && serverData["config"].isObject()) {
|
||
QJsonObject configObj = serverData["config"].toObject();
|
||
if (configObj.contains("cameraConfig") && configObj["cameraConfig"].isObject()) {
|
||
cameraConfig = configObj["cameraConfig"].toObject();
|
||
}
|
||
} else if (serverData.contains("cameraConfig") && serverData["cameraConfig"].isObject()) {
|
||
cameraConfig = serverData["cameraConfig"].toObject();
|
||
}
|
||
|
||
if (!cameraConfig.isEmpty() && cameraConfig.contains("cameraIP")) {
|
||
ui->lineEdit_cameraIP->setText(cameraConfig["cameraIP"].toString());
|
||
}
|
||
|
||
// 更新队列处理参数
|
||
QJsonObject queueConfig;
|
||
if (serverData.contains("config") && serverData["config"].isObject()) {
|
||
QJsonObject configObj = serverData["config"].toObject();
|
||
if (configObj.contains("queueProcessParam") && configObj["queueProcessParam"].isObject()) {
|
||
queueConfig = configObj["queueProcessParam"].toObject();
|
||
}
|
||
} else if (serverData.contains("queueProcessParam") && serverData["queueProcessParam"].isObject()) {
|
||
queueConfig = serverData["queueProcessParam"].toObject();
|
||
}
|
||
|
||
// 设置队列参数,如果服务器没有返回则使用默认值
|
||
if (!queueConfig.isEmpty()) {
|
||
if (queueConfig.contains("maxQueueSize")) {
|
||
ui->lineEdit_maxQueueSize->setText(QString::number(queueConfig["maxQueueSize"].toInt()));
|
||
} else {
|
||
ui->lineEdit_maxQueueSize->setText("300"); // 默认值
|
||
}
|
||
if (queueConfig.contains("generationInterval")) {
|
||
ui->lineEdit_generationInterval->setText(QString::number(queueConfig["generationInterval"].toInt()));
|
||
} else {
|
||
ui->lineEdit_generationInterval->setText("100"); // 默认值
|
||
}
|
||
if (queueConfig.contains("imageLineCount")) {
|
||
ui->lineEdit_imageLineCount->setText(QString::number(queueConfig["imageLineCount"].toInt()));
|
||
} else {
|
||
ui->lineEdit_imageLineCount->setText("300"); // 默认值
|
||
}
|
||
} else {
|
||
// 如果完全没有队列配置信息,使用默认值
|
||
ui->lineEdit_maxQueueSize->setText("300");
|
||
ui->lineEdit_generationInterval->setText("100");
|
||
ui->lineEdit_imageLineCount->setText("300");
|
||
}
|
||
|
||
QJsonObject pointCloudConfig;
|
||
if (serverData.contains("config") && serverData["config"].isObject()) {
|
||
QJsonObject configObj = serverData["config"].toObject();
|
||
if (configObj.contains("pointCloudSendParam") && configObj["pointCloudSendParam"].isObject()) {
|
||
pointCloudConfig = configObj["pointCloudSendParam"].toObject();
|
||
}
|
||
} else if (serverData.contains("pointCloudSendParam") && serverData["pointCloudSendParam"].isObject()) {
|
||
pointCloudConfig = serverData["pointCloudSendParam"].toObject();
|
||
}
|
||
|
||
ui->checkBox_pointCloudEnabled->setChecked(
|
||
pointCloudConfig.contains("enabled") ? pointCloudConfig["enabled"].toBool() : true);
|
||
ui->lineEdit_pointCloudLineStep->setText(QString::number(
|
||
pointCloudConfig.contains("lineStep") ? pointCloudConfig["lineStep"].toInt() : 1));
|
||
ui->lineEdit_pointCloudPointStep->setText(QString::number(
|
||
pointCloudConfig.contains("pointStep") ? pointCloudConfig["pointStep"].toInt() : 1));
|
||
}
|
||
|
||
void DialogAlgoarg::on_btn_camer_ok_clicked()
|
||
{
|
||
// 发送参数到服务器
|
||
if (!sendParametersToServer()) {
|
||
return;
|
||
}
|
||
|
||
StyledMessageBox::information(this, "成功", "配置保存成功并已发送到服务器!");
|
||
accept();
|
||
}
|
||
|
||
void DialogAlgoarg::on_btn_camer_cancel_clicked()
|
||
{
|
||
// 直接关闭窗口,不保存任何更改
|
||
reject();
|
||
}
|