diff --git a/src/GvfToCsv/GvfToCsv.h b/src/GvfToCsv/GvfToCsv.h index b0e5145..ebfe100 100644 --- a/src/GvfToCsv/GvfToCsv.h +++ b/src/GvfToCsv/GvfToCsv.h @@ -62,6 +62,7 @@ public: bool convertGVF2CSVSync(const QString &gvfPath, const QString &csvPath); // 添加错误信息获取 QString getLastError() const { return m_lastError; } + QList parseParticleFrames(const QByteArray &data); signals: void conversionProgress(int percent); @@ -73,7 +74,6 @@ private slots: private: void processDBData(); - QList parseParticleFrames(const QByteArray &data); void cleanUp(); // 添加错误信息存储 void setLastError(const QString& error) { m_lastError = error; emit errorOccurred(error); } diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 8766a57..beda50d 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -29,7 +29,10 @@ #include "NuclideLib.h" #include "BackgroundTaskListView.h" #include - +#include +#include +#include "MeasureClient.h" +#include "GvfToCsv/GvfToCsv.h" using namespace ads; MainWindow* MainWindow::_s_main_win = nullptr; @@ -90,6 +93,17 @@ MainWindow::MainWindow(QWidget* parent) { ui->setupUi(this); _status_bar = ui->statusbar; + _gvfToCsv = new GvfToCsv; + _measure_client = new MeasureClient; + connect(_measure_client, &MeasureClient::getDeviceListResult, this, &MainWindow::onGetDeviceListResult); + connect(_measure_client, &MeasureClient::startMeasureResult, this, &MainWindow::onStartMeasureResult); + connect(_measure_client, &MeasureClient::stopMeasureResult, this, &MainWindow::onStopMeasureResult); + connect(_measure_client, &MeasureClient::setMeasureConfigParamsResult, this, &MainWindow::onSetMeasureConfigParamsResult); + connect(_measure_client, &MeasureClient::clearDataResult, this, &MainWindow::onClearDataResult); + connect(_measure_client, &MeasureClient::runningInfo, this, &MainWindow::onRunningInfo); + connect(_measure_client, &MeasureClient::errorOccurred, this, &MainWindow::onErrorOccurred); + connect(_measure_client, &MeasureClient::gvfData, this, &MainWindow::onGvfData); + _measure_client->connectToServer(); initMainWindow(); initAction(); @@ -435,3 +449,160 @@ void MainWindow::resizeEvent(QResizeEvent *event) } } + +void MainWindow::on_action_start_measure_triggered() +{ + LOG_INFO(QStringLiteral(u"查找测量设备... ...")); + _measure_client->getDeviceList(); + LOG_INFO(QStringLiteral(u"开始测量... ...")); + QString device_guid; + if(deviceList.size()>0) + { + device_guid = deviceList.at(0); + } + MeasureAnalysisProjectModel* models = ProjectList::Instance()->GetCurrentProjectModel(); + QMap > project_node_items = ProjectList::Instance()->getProjectNodeItems(); + QMap node = project_node_items[models->GetProjectName()]; + QStandardItem *nodeItem = node[models->GetProjectName()]; + ProjectList::Instance()->SetNodeStatus(nodeItem,"测量中",true); + QString projectName; + QString deviceCfg; + if(models) + { + projectName = models->GetProjectName(); + deviceCfg = models->GetMeasureDeviceParamsCfgFilename(); + if(deviceCfg == "") + { + QMessageBox::information(this,"提示","设备参数配置未配置","确认","取消"); + } + } + + QFile json_file(deviceCfg); + if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + LOG_INFO(QStringLiteral(u"加载设备参数配置失败:%1").arg(deviceCfg)); + return; + } + QByteArray json_data = json_file.readAll(); + json_file.close(); + QJsonDocument json_doc = QJsonDocument::fromJson(json_data); + if (json_doc.isNull()) { + return; + } + if (!json_doc.isObject()) + return; + QVariantMap device_config_info = json_doc.object().toVariantMap(); + if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) + return; + QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList(); + if (channel_config_list.isEmpty()) { + LOG_INFO(QStringLiteral(u"测量设备通道配置参数为空.")); + return; + } + _measure_client->startMeasure(device_guid, device_config_info); +} + +void MainWindow::onStartMeasureResult(bool success, const QString &info) +{ + if(success) + { + LOG_INFO(QStringLiteral(u"启动测量成功")); + LOG_INFO(QStringLiteral(u"测量数据GVF文件: %1").arg(info)); + } + else + LOG_INFO(QStringLiteral(u"启动测量失败: %1").arg(info)); +} + +void MainWindow::onStopMeasureResult(bool success, const QString &message) +{ + if(success){ + LOG_INFO(QStringLiteral(u"停止测量成功")); + } + else + LOG_INFO(QStringLiteral(u"停止测量失败: %1").arg(message)); +} + +void MainWindow::onSetMeasureConfigParamsResult(bool success, const QString &message) +{ + if(success){ + LOG_INFO(QStringLiteral(u"设置测量参数成功")); + } + else + LOG_INFO(QStringLiteral(u"设置测量参数失败: %1").arg(message)); +} + +void MainWindow::onClearDataResult(bool success, const QString &message) +{ + if(success){ + LOG_INFO(QStringLiteral(u"清除测量数据成功")); + } + else + LOG_INFO(QStringLiteral(u"清除测量数据失败: %1").arg(message)); +} + +void MainWindow::onGetDeviceListResult(bool success, const QString &message, const QStringList &devices) +{ + if (success) { + deviceList = devices; + } + //测试 + deviceList.append("0x01"); +} + +void MainWindow::onErrorOccurred(const QString &error_string) +{ + LOG_INFO(QStringLiteral(u"错误: %1").arg(error_string)); +} + +void MainWindow::onRunningInfo(const QString &run_info) +{ + LOG_INFO(QStringLiteral(u"信息: %1").arg(run_info)); +} + +void MainWindow::onGvfData(const QByteArray &data) +{ + LOG_INFO(QStringLiteral(u"GVFDATA: %1").arg(QString::fromUtf8(data.toHex().toUpper()))); + QList particles = _gvfToCsv->parseParticleFrames(data); + if (particles.isEmpty()) { + LOG_INFO(QStringLiteral(u"本次GVF数据未解析到有效粒子,跳过写入CSV")); + return; + } + QString dir = ProjectList::Instance()->GetCurrentProjectModel()->GetProjectDir(); + QString csvPath = QStringLiteral(u"%1/%2").arg(dir).arg("粒子数据.csv"); + + QFile outFile(csvPath); + if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { + LOG_ERROR(QStringLiteral(u"无法打开CSV文件(追加模式): %1,错误: %2") + .arg(csvPath) + .arg(outFile.errorString())); + return; + } + + QTextStream out(&outFile); + out.setCodec("UTF-8"); + + if (outFile.size() == 0) { + out << QStringLiteral(u"板卡号,通道号,道址,时间计数\n"); + LOG_INFO(QStringLiteral(u"CSV文件为空,已自动写入表头: %1").arg(csvPath)); + } + + QString csvBuffer; + csvBuffer.reserve(particles.size() * 64); // 单条数据约64字节,预分配足够内存 + + for (const auto &p : particles) { + csvBuffer += QString("%1,%2,%3,%4\n") + .arg(p.boardId) + .arg(p.channelId) + .arg(p.address) + .arg(p.timestampCount); + } + + out << csvBuffer; + out.flush(); // 确保数据立即写入磁盘,避免程序崩溃丢失数据 + outFile.close(); + + LOG_INFO(QStringLiteral(u"已成功追加写入%1条粒子数据到CSV文件: %2") + .arg(particles.size()) + .arg(csvPath)); + +} + diff --git a/src/MainWindow.h b/src/MainWindow.h index 625c7fd..4c0b82d 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -17,6 +17,8 @@ class QPlainTextEdit; class MeasureAnalysisTreeView; class BackgroundTaskListView; class QPushButton; +class MeasureClient; +class GvfToCsv; QT_END_NAMESPACE class MainWindow : public QMainWindow @@ -64,6 +66,18 @@ private slots: void on_action_nuclideLib_triggered(); void onShowBackgroundTaskList(); + void on_action_start_measure_triggered(); + + + void onStartMeasureResult(bool success, const QString& info); + void onStopMeasureResult(bool success, const QString& message); + void onSetMeasureConfigParamsResult(bool success, const QString& message); + void onClearDataResult(bool success, const QString& message); + void onGetDeviceListResult(bool success, const QString &message, const QStringList &devices); + void onErrorOccurred(const QString &error_string); + void onRunningInfo(const QString &run_info); + void onGvfData(const QByteArray& data); + private: QMutex _mutex_info_output; QPlainTextEdit* _plain_edit_info_output; @@ -80,5 +94,9 @@ private: ads::CDockWidget* _dockw_measure_analysis_tree { nullptr }; QMenu* _menu_view_data_table_list { nullptr }; QMenu* _menu_view_analysis_view_list { nullptr }; + MeasureClient* _measure_client = nullptr; + QStringList deviceList; + GvfToCsv *_gvfToCsv = nullptr; + }; #endif // MAINWINDOW_H diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 29f67b2..8aa639d 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -803,6 +803,11 @@ void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_na } } +QMap > MeasureAnalysisProjectModelList::getProjectNodeItems() +{ + return _project_node_items; +} + void MeasureAnalysisProjectModelList::onDeviceConfigParamsFinished(bool ok, const QString &project_name, const QVariant &data) { Q_UNUSED(data); diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index 5a2d845..bc2a4e8 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -162,6 +162,8 @@ public: void ApplyEnergyScale(const QString& project_name); + QMap > getProjectNodeItems(); + private slots: void onDeviceConfigParamsFinished(bool ok, const QString& project_name, const QVariant& data); void onChannelAddressCountProcessFinished(bool ok, const QString& project_name, const QVariant& data);