完善图表配置功能,修改设备连接管理标题

This commit is contained in:
anxinglong 2026-07-28 17:55:49 +08:00
parent 8ee6c4387c
commit 0228b347ce
6 changed files with 303 additions and 36 deletions

View File

@ -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");

View File

@ -10,6 +10,8 @@
#include <QLabel>
#include <QHBoxLayout>
#include <QShowEvent>
#include <QProcess>
#include <QDateTime>
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<QString, QMap<QString, QStandardItem *> > project_node_items = ProjectList::Instance()->getProjectNodeItems();
QMap<QString, QStandardItem *> 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地址"));

View File

@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>设备连接管理</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="7">

View File

@ -3,22 +3,16 @@
#include "PlotRectItem.h"
#include "csv.h"
#include <GlobalDefine.h>
#include <QCheckBox>
#include <QDebug>
#include <QDialog>
#include <QFileInfo>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QMenu>
#include <QPushButton>
#include <QwtLegend>
#include <QwtPlotCanvas>
#include <QwtPlotCurve>
#include <QwtPlotMarker>
#include <QwtScaleDiv>
#include <QwtScaleMap>
#include <QwtText>
#include <QDialog>
#include <QPushButton>
#include <QCheckBox>
#include <QwtScaleDiv>
@ -29,14 +23,12 @@
#include <QMessageBox>
#include <QListWidget>
#include <QDateTime>
#include <QDir>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDir>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QColorDialog>
#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<double>(), QVector<double>());
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<double>(), QVector<double>());
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<double>(), QVector<double>());
dummyBg->setVisible(false);
dummyBg->attach(_plot);
QwtPlotCurve *dummyBg = new QwtPlotCurve(QStringLiteral(u"本底数据"));
dummyBg->setPen(QPen(QColor("#C9A84C"), 2));
dummyBg->setSamples(QVector<double>(), QVector<double>());
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<QwtPlotCurve*> curveList;
// QMap<QwtPlotCurve*, QColor> curveColorMap;
// const QwtPlotItemList& items = _plot->itemList();
// for (QwtPlotItem* item : items) {
// if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
// QwtPlotCurve* curve = static_cast<QwtPlotCurve*>(item);
// curveList.append(curve);
// curveColorMap.insert(curve, curve->pen().color());
// }
// }
// // 为每条曲线创建颜色按钮
// QList<QPushButton*> 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<QwtPlotCurve*>(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));
}

View File

@ -21,6 +21,11 @@
#include <QwtScaleWidget>
#include <QThreadPool>
#include "BusyIndicator.h"
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QDoubleSpinBox>
#include <QColorDialog>
#include <QPen>
#include <QDebug>
@ -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, &current_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<double, unsigned long long> hist_map;
for (const unsigned long long& d_time : _time_diffs) {
double bin = floor(static_cast<double>(d_time) / _bin_width) * _bin_width;
hist_map[bin]++;
}
QVector<QwtIntervalSample> 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<double>(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()));
}

View File

@ -6,6 +6,7 @@
#include <MeasureAnalysisView.h>
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<unsigned long long> _time_diffs;
};
#endif // PARTICLETIMEDIFFERENCEVIEW_H