diff --git a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp index c40c28e..5ff5fd0 100644 --- a/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp +++ b/src/2DSpectralCompliance/TwoDSpectralCompliance.cpp @@ -165,9 +165,9 @@ void TwoDSpectralCompliance::setupMenu() this->_plot->ResetPlot(); }); this->_menu->addSeparator(); - QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置")); - action_plot_config->setObjectName("plot_config"); - connect(action_plot_config, &QAction::triggered, this, &TwoDSpectralCompliance::onActionPlotConfigure); + // QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置")); + // action_plot_config->setObjectName("plot_config"); + // connect(action_plot_config, &QAction::triggered, this, &TwoDSpectralCompliance::onActionPlotConfigure); QAction* action_roi = this->_menu->addAction(QStringLiteral(u"感兴趣区")); action_roi->setObjectName("roi"); diff --git a/src/DeviceConnectManagement.cpp b/src/DeviceConnectManagement.cpp index bae2962..f19d837 100644 --- a/src/DeviceConnectManagement.cpp +++ b/src/DeviceConnectManagement.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include DeviceConnectManagement::DeviceConnectManagement(MeasureClient* client, QWidget *parent) : QDialog(parent) @@ -112,6 +114,14 @@ bool DeviceConnectManagement::startMeasure() void DeviceConnectManagement::stopMeasure() { + //获取当前项目 + MeasureAnalysisProjectModel* projectModel = ProjectList::Instance()->GetCurrentProjectModel(); + projectModel->SetIsMeasureComplete(true);//设置测量完成 + QMap > project_node_items = ProjectList::Instance()->getProjectNodeItems(); + QMap nodeMap = project_node_items[projectModel->GetProjectName()]; + QStandardItem *nodeItem = nodeMap[projectModel->GetProjectName()]; + ProjectList::Instance()->SetNodeStatus(nodeItem,"测量完成",true); + QString deviceId = getCurrentDeviceId(); if (deviceId.isEmpty() && !m_deviceList.isEmpty()) { deviceId = m_deviceList.first(); @@ -178,6 +188,11 @@ void DeviceConnectManagement::updateDeviceList(const QStringList& devices, bool void DeviceConnectManagement::on_pBtn_connectService_clicked() { + QProcess *proc = new QProcess; + //获取当前运行程序目录 + QString exeFullPath = QCoreApplication::applicationDirPath() + "/EnergySpectrumMeasureService/EnergySpectrumMeasureService.exe"; + proc->start(exeFullPath); + QString ip = getServerIp(); if (ip.isEmpty()) { QMessageBox::warning(this, QStringLiteral(u"提示"), QStringLiteral(u"请输入服务器IP地址")); diff --git a/src/DeviceConnectManagement.ui b/src/DeviceConnectManagement.ui index 0288c52..3085b95 100644 --- a/src/DeviceConnectManagement.ui +++ b/src/DeviceConnectManagement.ui @@ -11,7 +11,7 @@ - Dialog + 设备连接管理 diff --git a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp index 1051811..5f0c54e 100644 --- a/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp +++ b/src/EnergyCountPeakFitView/EnergyCountPeakFitView.cpp @@ -3,22 +3,16 @@ #include "PlotRectItem.h" #include "csv.h" #include -#include #include #include -#include #include -#include #include -#include #include #include #include #include -#include #include #include -#include #include #include #include @@ -29,14 +23,12 @@ #include #include #include -#include -#include #include -#include #include #include #include #include +#include #include "MeasureAnalysisProjectModel.h" #include "BusyIndicator.h" @@ -217,29 +209,27 @@ void EnergyCountPeakFitView::setupPlot() _plot->setAxisAutoScale(QwtPlot::xBottom, true); _plot->setAxisAutoScale(QwtPlot::yLeft, true); - - _plot->enableAxis(QwtPlot::xBottom); _plot->enableAxis(QwtPlot::yLeft); - QwtLegend* legend = new QwtLegend(); - legend->setDefaultItemMode(QwtLegendData::ReadOnly); - _plot->insertLegend(legend, QwtPlot::RightLegend); - _plot->SetAxisDragScale(QwtPlot::xBottom, true); - _plot->SetAxisDragScale(QwtPlot::yLeft, true); + QwtLegend* legend = new QwtLegend(); + legend->setDefaultItemMode(QwtLegendData::ReadOnly); + _plot->insertLegend(legend, QwtPlot::RightLegend); + _plot->SetAxisDragScale(QwtPlot::xBottom, true); + _plot->SetAxisDragScale(QwtPlot::yLeft, true); - QwtPlotCurve *dummyFit = new QwtPlotCurve(QStringLiteral(u"拟合数据")); - dummyFit->setPen(QPen(Qt::blue, 2)); - dummyFit->setSamples(QVector(), QVector()); - dummyFit->setVisible(false); - dummyFit->setItemAttribute(QwtPlotItem::Legend, true); - dummyFit->attach(_plot); + QwtPlotCurve *dummyFit = new QwtPlotCurve(QStringLiteral(u"拟合数据")); + dummyFit->setPen(QPen(Qt::blue, 2)); + dummyFit->setSamples(QVector(), QVector()); + dummyFit->setVisible(false); + dummyFit->setItemAttribute(QwtPlotItem::Legend, true); + dummyFit->attach(_plot); - QwtPlotCurve *dummyBg = new QwtPlotCurve(QStringLiteral(u"本底数据")); - dummyBg->setPen(QPen(QColor("#C9A84C"), 2)); - dummyBg->setSamples(QVector(), QVector()); - dummyBg->setVisible(false); - dummyBg->attach(_plot); + QwtPlotCurve *dummyBg = new QwtPlotCurve(QStringLiteral(u"本底数据")); + dummyBg->setPen(QPen(QColor("#C9A84C"), 2)); + dummyBg->setSamples(QVector(), QVector()); + dummyBg->setVisible(false); + dummyBg->attach(_plot); _data_selector = new CustomQwtPlotXaxisSelector(_plot->canvas()); _data_selector->setEnabled(false); @@ -406,7 +396,133 @@ void EnergyCountPeakFitView::onActionCurveShowSetting() void EnergyCountPeakFitView::onActionPlotConfigure() { + QDialog dlg(this); + dlg.setWindowTitle(QStringLiteral(u"图表配置")); + dlg.setMinimumWidth(320); + QVBoxLayout* layout = new QVBoxLayout(&dlg); + + // X轴标题 + QHBoxLayout* xTitleLayout = new QHBoxLayout(); + QLabel* xTitleLabel = new QLabel(QStringLiteral(u"X轴标题:"), &dlg); + QLineEdit* xTitleEdit = new QLineEdit(_plot->axisTitle(QwtPlot::xBottom).text(), &dlg); + xTitleLayout->addWidget(xTitleLabel); + xTitleLayout->addWidget(xTitleEdit); + layout->addLayout(xTitleLayout); + + // Y轴标题 + QHBoxLayout* yTitleLayout = new QHBoxLayout(); + QLabel* yTitleLabel = new QLabel(QStringLiteral(u"Y轴标题:"), &dlg); + QLineEdit* yTitleEdit = new QLineEdit(_plot->axisTitle(QwtPlot::yLeft).text(), &dlg); + yTitleLayout->addWidget(yTitleLabel); + yTitleLayout->addWidget(yTitleEdit); + layout->addLayout(yTitleLayout); + + layout->addSpacing(8); + + // 显示网格 + QCheckBox* gridCheck = new QCheckBox(QStringLiteral(u"显示网格线"), &dlg); + gridCheck->setChecked(_plot->axisEnabled(QwtPlot::xBottom) && _plot->axisEnabled(QwtPlot::yLeft)); + layout->addWidget(gridCheck); + + // 显示图例 + QCheckBox* legendCheck = new QCheckBox(QStringLiteral(u"显示图例"), &dlg); + legendCheck->setChecked(_plot->legend() != nullptr); + layout->addWidget(legendCheck); + + layout->addSpacing(8); + + // // 曲线颜色 + // QLabel* curveColorLabel = new QLabel(QStringLiteral(u"曲线颜色:"), &dlg); + // layout->addWidget(curveColorLabel); + + // // 获取所有曲线 + // QList curveList; + // QMap curveColorMap; + // const QwtPlotItemList& items = _plot->itemList(); + // for (QwtPlotItem* item : items) { + // if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) { + // QwtPlotCurve* curve = static_cast(item); + // curveList.append(curve); + // curveColorMap.insert(curve, curve->pen().color()); + // } + // } + + // // 为每条曲线创建颜色按钮 + // QList colorBtnList; + // for (int i = 0; i < curveList.size(); ++i) { + // QwtPlotCurve* curve = curveList.at(i); + // QHBoxLayout* btnLayout = new QHBoxLayout(); + // QLabel* nameLabel = new QLabel(QStringLiteral(u"曲线%1").arg(i + 1), &dlg); + // QPushButton* colorBtn = new QPushButton(&dlg); + // colorBtn->setFixedSize(60, 24); + // QColor color = curveColorMap.value(curve); + // colorBtn->setStyleSheet(QString("background-color: %1; border: 1px solid #999;") + // .arg(color.name())); + // btnLayout->addWidget(nameLabel); + // btnLayout->addWidget(colorBtn); + // btnLayout->addStretch(); + // layout->addLayout(btnLayout); + // colorBtnList.append(colorBtn); + + // connect(colorBtn, &QPushButton::clicked, [&dlg, curve, &curveColorMap, colorBtn]() { + // QColor current = curveColorMap.value(curve); + // QColor selected = QColorDialog::getColor(current, &dlg, QStringLiteral(u"选择曲线颜色")); + // if (selected.isValid()) { + // curveColorMap[curve] = selected; + // colorBtn->setStyleSheet(QString("background-color: %1; border: 1px solid #999;") + // .arg(selected.name())); + // } + // }); + // } + + // layout->addStretch(); + + // 确定取消按钮 + QDialogButtonBox* buttonBox = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dlg); + layout->addWidget(buttonBox); + + connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject); + + if (dlg.exec() == QDialog::Accepted) { + // 应用X轴标题 + _plot->setAxisTitle(QwtPlot::xBottom, xTitleEdit->text()); + // 应用Y轴标题 + _plot->setAxisTitle(QwtPlot::yLeft, yTitleEdit->text()); + // 应用网格显示 + _plot->enableAxis(QwtPlot::xBottom, gridCheck->isChecked()); + _plot->enableAxis(QwtPlot::yLeft, gridCheck->isChecked()); + // 应用图例显示 + if (legendCheck->isChecked() && _plot->legend() == nullptr) { + QwtLegend* legend = new QwtLegend(); + legend->setDefaultItemMode(QwtLegendData::ReadOnly); + _plot->insertLegend(legend, QwtPlot::RightLegend); + // 给未命名曲线设置默认标题,保证图例显示名称 + int idx = 1; + const QwtPlotItemList& items = _plot->itemList(); + for (QwtPlotItem* item : items) { + if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) { + QwtPlotCurve* curve = static_cast(item); + if (curve->title().isEmpty()) { + curve->setTitle(QStringLiteral(u"曲线%1").arg(idx)); + } + ++idx; + } + } + } else if (!legendCheck->isChecked() && _plot->legend() != nullptr) { + _plot->insertLegend(nullptr); + } + // // 应用曲线颜色 + // for (QwtPlotCurve* curve : curveList) { + // QPen pen = curve->pen(); + // pen.setColor(curveColorMap.value(curve)); + // curve->setPen(pen); + // } + // 刷新绘图 + _plot->replot(); + } } void EnergyCountPeakFitView::clearAllSelectionRects() @@ -916,8 +1032,6 @@ void EnergyCountPeakFitView::onActionShowFitHistory() rowItems.append(new QStandardItem(QString::number(curve.sigmoidH, 'f', 4))); rowItems.append(new QStandardItem(QString::number(curve.sigmoidW, 'f', 4))); rowItems.append(new QStandardItem(QString::number(curve.baseline, 'f', 4))); - - model->appendRow(rowItems); rowToDataIndices.append(qMakePair(historyIdx, curveIdx)); } diff --git a/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.cpp b/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.cpp index f2b124a..1e24846 100644 --- a/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.cpp +++ b/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.cpp @@ -21,6 +21,11 @@ #include #include #include "BusyIndicator.h" +#include +#include +#include +#include +#include #include @@ -28,7 +33,7 @@ ParticleTimeDifferenceView::ParticleTimeDifferenceView(QWidget *parent) : MeasureAnalysisView { parent } { this->setViewType(PlotFrame); - + _histogram_color = QColor(0, 0, 0); QHBoxLayout* layout = new QHBoxLayout(this); this->_plot = new CustomQwtPlot(this); layout->addWidget(this->_plot); @@ -175,7 +180,95 @@ void ParticleTimeDifferenceView::loadDataFromFile() void ParticleTimeDifferenceView::onActionPlotConfigure() { - + QDialog* dlg = new QDialog(this); + dlg->setWindowTitle(QStringLiteral(u"图表配置")); + dlg->setMinimumWidth(320); + QVBoxLayout* main_layout = new QVBoxLayout(dlg); + QFormLayout* form_layout = new QFormLayout(); + // X轴范围 + QDoubleSpinBox* spin_x_min = new QDoubleSpinBox(dlg); + spin_x_min->setRange(0.0, 1e9); + spin_x_min->setDecimals(2); + spin_x_min->setSuffix(QStringLiteral(u" ns")); + spin_x_min->setValue(_x_min); + form_layout->addRow(QStringLiteral(u"X轴最小值:"), spin_x_min); + QDoubleSpinBox* spin_x_max = new QDoubleSpinBox(dlg); + spin_x_max->setRange(0.0, 1e9); + spin_x_max->setDecimals(2); + spin_x_max->setSuffix(QStringLiteral(u" ns")); + spin_x_max->setValue(_x_max); + form_layout->addRow(QStringLiteral(u"X轴最大值:"), spin_x_max); + // Y轴范围 + QDoubleSpinBox* spin_y_min = new QDoubleSpinBox(dlg); + spin_y_min->setRange(0.0, 1e9); + spin_y_min->setDecimals(0); + spin_y_min->setSuffix(QStringLiteral(u" 个")); + spin_y_min->setValue(_y_min); + form_layout->addRow(QStringLiteral(u"Y轴最小值:"), spin_y_min); + QDoubleSpinBox* spin_y_max = new QDoubleSpinBox(dlg); + spin_y_max->setRange(0.0, 1e9); + spin_y_max->setDecimals(0); + spin_y_max->setSuffix(QStringLiteral(u" 个")); + spin_y_max->setValue(_y_max); + form_layout->addRow(QStringLiteral(u"Y轴最大值:"), spin_y_max); + // Bin宽度 + QDoubleSpinBox* spin_bin_width = new QDoubleSpinBox(dlg); + spin_bin_width->setRange(1.0, 1e6); + spin_bin_width->setDecimals(2); + spin_bin_width->setSuffix(QStringLiteral(u" ns")); + spin_bin_width->setValue(_bin_width); + form_layout->addRow(QStringLiteral(u"Bin宽度:"), spin_bin_width); + // 柱状图颜色 + QPushButton* btn_color = new QPushButton(dlg); + btn_color->setFixedHeight(28); + QColor current_color = _histogram_color; + auto updateColorButton = [btn_color](const QColor& color) { + QString style = QStringLiteral("background-color: %1; border: 1px solid #888;") + .arg(color.name()); + btn_color->setStyleSheet(style); + }; + updateColorButton(current_color); + connect(btn_color, &QPushButton::clicked, [this, dlg, btn_color, ¤t_color, updateColorButton]() { + QColor color = QColorDialog::getColor(_histogram_color, dlg, QStringLiteral(u"选择柱状图颜色")); + if (color.isValid()) { + current_color = color; + updateColorButton(color); + } + }); + form_layout->addRow(QStringLiteral(u"柱状图颜色:"), btn_color); + main_layout->addLayout(form_layout); + // 按钮 + QDialogButtonBox* button_box = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel, dlg); + button_box->button(QDialogButtonBox::Ok)->setText(QStringLiteral(u"确定")); + button_box->button(QDialogButtonBox::Cancel)->setText(QStringLiteral(u"取消")); + main_layout->addWidget(button_box); + connect(button_box, &QDialogButtonBox::accepted, dlg, &QDialog::accept); + connect(button_box, &QDialogButtonBox::rejected, dlg, &QDialog::reject); + if (dlg->exec() == QDialog::Accepted) { + double x_min = spin_x_min->value(); + double x_max = spin_x_max->value(); + double y_min = spin_y_min->value(); + double y_max = spin_y_max->value(); + double bin_width = spin_bin_width->value(); + if (x_min >= x_max) { + LOG_WARN(QStringLiteral(u"图表配置: X轴最小值必须小于最大值")); + dlg->deleteLater(); + return; + } + if (y_min >= y_max) { + LOG_WARN(QStringLiteral(u"图表配置: Y轴最小值必须小于最大值")); + dlg->deleteLater(); + return; + } + if (bin_width <= 0) { + LOG_WARN(QStringLiteral(u"图表配置: Bin宽度必须大于0")); + dlg->deleteLater(); + return; + } + applyPlotConfig(x_min, x_max, y_min, y_max, bin_width, current_color); + } + dlg->deleteLater(); } void ParticleTimeDifferenceView::showEvent(QShowEvent *e) @@ -185,4 +278,43 @@ void ParticleTimeDifferenceView::showEvent(QShowEvent *e) _busy_indicator->setGeometry(this->rect()); this->update(); } +} + +void ParticleTimeDifferenceView::applyPlotConfig(double x_min, double x_max, + double y_min, double y_max, + double bin_width, + const QColor& color) +{ + bool bin_changed = (bin_width != _bin_width); + bool color_changed = (color != _histogram_color); + _bin_width = bin_width; + _x_min = x_min; + _x_max = x_max; + _y_min = y_min; + _y_max = y_max; + _histogram_color = color; + if (bin_changed && !_time_diffs.isEmpty()) { + // Bin宽度改变时需要重新分箱计算直方图 + QMap hist_map; + for (const unsigned long long& d_time : _time_diffs) { + double bin = floor(static_cast(d_time) / _bin_width) * _bin_width; + hist_map[bin]++; + } + QVector samples; + for (const double& bin : hist_map.keys()) { + const unsigned long long& count = hist_map.value(bin); + double bin_max = bin + _bin_width; + samples.append(QwtIntervalSample(static_cast(count), bin, bin_max)); + } + _histogram->setData(new QwtIntervalSeriesData(samples)); + } + if (color_changed || bin_changed) { + _histogram->setBrush(QBrush(_histogram_color)); + _histogram->setPen(QPen(_histogram_color.darker(120))); + } + _plot->setAxisScale(QwtPlot::xBottom, _x_min, _x_max); + _plot->setAxisScale(QwtPlot::yLeft, _y_min, _y_max); + _plot->replot(); + LOG_INFO(QStringLiteral(u"图表配置已应用: X[%1, %2] Y[%3, %4] Bin=%5 Color=%6") + .arg(_x_min).arg(_x_max).arg(_y_min).arg(_y_max).arg(_bin_width).arg(_histogram_color.name())); } \ No newline at end of file diff --git a/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.h b/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.h index 1fa6189..b8fd58b 100644 --- a/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.h +++ b/src/ParticleTimeDifferenceView/ParticleTimeDifferenceView.h @@ -6,6 +6,7 @@ #include class QMenu; +class QColor; class CustomQwtPlot; class CustomQwtPlotXaxisSelector; class QwtPlotHistogram; @@ -25,7 +26,8 @@ private: void setupPlot(); void setupMenu(); void loadDataFromFile(); - + void applyPlotConfig(double x_min, double x_max, double y_min, double y_max, double bin_width, const QColor& color); + void rebuildHistogram(); private slots: void onActionPlotConfigure(); @@ -39,10 +41,14 @@ private: QDialog* _curve_show_setting_dlg = nullptr; CustomQwtPlotXaxisSelector* _data_selector = nullptr; double _bin_width = 50.0f; + double _x_min = 0.0f; double _x_max = 200.0f * 1e3; + double _y_min = 0.0f; double _y_max = 0.0f; QwtPlotHistogram* _histogram = nullptr; + QColor _histogram_color; QString _data_filename; + QVector _time_diffs; }; #endif // PARTICLETIMEDIFFERENCEVIEW_H