GrabBag/BeltTearingConfig/Src/VrBeltTearingConfig.cpp

236 lines
9.9 KiB
C++
Raw Normal View History

#include "VrBeltTearingConfig.h"
#include "IVrBeltTearingConfig.h"
#include <algorithm>
#include <sstream>
2025-08-31 21:08:28 +08:00
#include "VrLog.h"
#include <QFile>
#include <QTextStream>
#include <QString>
#include <QTextCodec>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
VrBeltTearingConfig::VrBeltTearingConfig()
: m_notify(nullptr)
{
}
VrBeltTearingConfig::~VrBeltTearingConfig()
{
}
// Also add the static CreateInstance method to the interface class
bool IVrBeltTearingConfig::CreateInstance(IVrBeltTearingConfig** ppVrConfig)
{
if (!ppVrConfig) {
return false;
}
*ppVrConfig = new VrBeltTearingConfig();
return true;
}
BeltTearingConfigResult VrBeltTearingConfig::LoadConfig(const std::string& filePath)
{
BeltTearingConfigResult result;
2025-08-31 21:08:28 +08:00
// 使用QString处理可能包含中文的路径
QString qFilePath = QString::fromStdString(filePath);
QFile file(qFilePath);
// 检查文件是否存在并可读
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
LOG_DEBUG("Failed to open file: %s\n", filePath.c_str());
return result;
}
// 使用QXmlStreamReader解析XML内容
QXmlStreamReader xml(&file);
// 读取到根元素
if (xml.readNextStartElement()) {
if (xml.name() != "BeltTearingConfig") {
xml.raiseError(QObject::tr("Not a BeltTearingConfig file"));
}
} else {
xml.raiseError(QObject::tr("Failed to read root element"));
}
// 解析XML内容
while (!xml.atEnd() && !xml.hasError()) {
xml.readNext();
// 解析服务器配置
if (xml.isStartElement() && xml.name() == "Servers") {
while (xml.readNextStartElement()) {
if (xml.name() == "Server") {
ServerInfo server;
server.name = xml.attributes().value("name").toString().toStdString();
server.ip = xml.attributes().value("ip").toString().toStdString();
server.port = xml.attributes().value("port").toInt();
result.servers.push_back(server);
xml.skipCurrentElement();
}
}
}
// 解析算法参数
else if (xml.isStartElement() && xml.name() == "AlgorithmParams") {
while (xml.readNextStartElement()) {
// 皮带撕裂参数
if (xml.name() == "BeltTearingParam") {
result.algorithmParams.beltTearingParam.tearThreshold =
xml.attributes().value("TearThreshold").toDouble();
result.algorithmParams.beltTearingParam.minTearLength =
xml.attributes().value("MinTearLength").toDouble();
result.algorithmParams.beltTearingParam.maxTearWidth =
xml.attributes().value("MaxTearWidth").toDouble();
xml.skipCurrentElement();
}
// 图像处理参数
else if (xml.name() == "ImageProcessingParam") {
result.algorithmParams.imageProcessingParam.blurSize =
xml.attributes().value("BlurSize").toInt();
result.algorithmParams.imageProcessingParam.cannyThreshold1 =
xml.attributes().value("CannyThreshold1").toInt();
result.algorithmParams.imageProcessingParam.cannyThreshold2 =
xml.attributes().value("CannyThreshold2").toInt();
result.algorithmParams.imageProcessingParam.morphologySize =
xml.attributes().value("MorphologySize").toInt();
xml.skipCurrentElement();
}
// 监控参数
else if (xml.name() == "MonitoringParam") {
result.algorithmParams.monitoringParam.checkInterval =
xml.attributes().value("CheckInterval").toInt();
result.algorithmParams.monitoringParam.alertThreshold =
xml.attributes().value("AlertThreshold").toInt();
result.algorithmParams.monitoringParam.maxHistorySize =
xml.attributes().value("MaxHistorySize").toInt();
xml.skipCurrentElement();
}
else {
xml.skipCurrentElement();
}
}
}
// 解析调试参数
else if (xml.isStartElement() && xml.name() == "DebugParam") {
result.debugParam.enableDebug = xml.attributes().value("enableDebug").toInt();
result.debugParam.saveDebugImage = xml.attributes().value("saveDebugImage").toInt();
result.debugParam.printDetailLog = xml.attributes().value("printDetailLog").toInt();
result.debugParam.debugOutputPath = xml.attributes().value("debugOutputPath").toString().toStdString();
xml.skipCurrentElement();
}
// 解析项目类型
else if (xml.isStartElement() && xml.name() == "ProjectType") {
QString typeStr = xml.attributes().value("type").toString();
if (typeStr == "BeltMonitoring") {
result.projectType = BeltTearingProjectType::BeltMonitoring;
} else {
result.projectType = BeltTearingProjectType::BeltTearing;
}
xml.skipCurrentElement();
}
}
file.close();
// 检查解析错误
if (xml.hasError()) {
LOG_ERROR("XML parsing error: %s\n", xml.errorString().toStdString().c_str());
return BeltTearingConfigResult(); // 返回空结果
}
return result;
}
bool VrBeltTearingConfig::SaveConfig(const std::string& filePath, BeltTearingConfigResult& configResult)
{
// 使用QString处理可能包含中文的路径
QString qFilePath = QString::fromStdString(filePath);
QFile file(qFilePath);
// 打开文件进行写入
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
LOG_DEBUG("Failed to open file for writing: %s\n", filePath.c_str());
return false;
}
// 使用QXmlStreamWriter写入XML内容
QXmlStreamWriter xml(&file);
xml.setAutoFormatting(true);
xml.setCodec("UTF-8"); // Explicitly set UTF-8 encoding to handle Chinese characters correctly
xml.writeStartDocument();
// 设置编码为UTF-8以正确处理中文
xml.writeStartElement("BeltTearingConfig");
// 保存服务器配置
if (!configResult.servers.empty()) {
xml.writeStartElement("Servers");
for (const auto& server : configResult.servers) {
xml.writeStartElement("Server");
xml.writeAttribute("name", QString::fromStdString(server.name));
xml.writeAttribute("ip", QString::fromStdString(server.ip));
xml.writeAttribute("port", QString::number(server.port));
xml.writeEndElement(); // Server
}
xml.writeEndElement(); // Servers
}
// 保存算法参数
xml.writeStartElement("AlgorithmParams");
// 皮带撕裂参数
xml.writeStartElement("BeltTearingParam");
xml.writeAttribute("TearThreshold", QString::number(configResult.algorithmParams.beltTearingParam.tearThreshold));
xml.writeAttribute("MinTearLength", QString::number(configResult.algorithmParams.beltTearingParam.minTearLength));
xml.writeAttribute("MaxTearWidth", QString::number(configResult.algorithmParams.beltTearingParam.maxTearWidth));
xml.writeEndElement(); // BeltTearingParam
// 图像处理参数
xml.writeStartElement("ImageProcessingParam");
xml.writeAttribute("BlurSize", QString::number(configResult.algorithmParams.imageProcessingParam.blurSize));
xml.writeAttribute("CannyThreshold1", QString::number(configResult.algorithmParams.imageProcessingParam.cannyThreshold1));
xml.writeAttribute("CannyThreshold2", QString::number(configResult.algorithmParams.imageProcessingParam.cannyThreshold2));
xml.writeAttribute("MorphologySize", QString::number(configResult.algorithmParams.imageProcessingParam.morphologySize));
xml.writeEndElement(); // ImageProcessingParam
// 监控参数
xml.writeStartElement("MonitoringParam");
xml.writeAttribute("CheckInterval", QString::number(configResult.algorithmParams.monitoringParam.checkInterval));
xml.writeAttribute("AlertThreshold", QString::number(configResult.algorithmParams.monitoringParam.alertThreshold));
xml.writeAttribute("MaxHistorySize", QString::number(configResult.algorithmParams.monitoringParam.maxHistorySize));
xml.writeEndElement(); // MonitoringParam
xml.writeEndElement(); // AlgorithmParams
// 保存调试参数
xml.writeStartElement("DebugParam");
xml.writeAttribute("enableDebug", QString::number(configResult.debugParam.enableDebug));
xml.writeAttribute("saveDebugImage", QString::number(configResult.debugParam.saveDebugImage));
xml.writeAttribute("printDetailLog", QString::number(configResult.debugParam.printDetailLog));
xml.writeAttribute("debugOutputPath", QString::fromStdString(configResult.debugParam.debugOutputPath));
xml.writeEndElement(); // DebugParam
// 保存项目类型
xml.writeStartElement("ProjectType");
QString typeStr = (configResult.projectType == BeltTearingProjectType::BeltMonitoring) ? "BeltMonitoring" : "BeltTearing";
xml.writeAttribute("type", typeStr);
xml.writeEndElement(); // ProjectType
xml.writeEndElement(); // BeltTearingConfig
xml.writeEndDocument();
2025-08-31 21:08:28 +08:00
file.close();
return true;
}
void VrBeltTearingConfig::SetConfigChangeNotify(IVrBeltTearingConfigChangeNotify* notify)
{
m_notify = notify;
}