1、修改添加图表的还原
2、修改bug 3、更新测量数据接收代码
This commit is contained in:
parent
cbb56426ec
commit
d1d5b1d3d0
|
|
@ -1,34 +1,34 @@
|
|||
#include "TwoDSpectralCompliance.h"
|
||||
#include "ui_TwoDSpectralCompliance.h"
|
||||
#include "BusyIndicator.h"
|
||||
#include "CustomQwtPlot.h"
|
||||
#include <QwtPlotCanvas>
|
||||
#include <QwtText>
|
||||
#include <QwtLegend>
|
||||
#include <QwtPlotSpectrogram>
|
||||
#include <QwtLinearColorMap>
|
||||
#include <QwtMatrixRasterData>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include "ui_TwoDSpectralCompliance.h"
|
||||
#include <QDebug>
|
||||
#include <cmath>
|
||||
#include <QwtInterval>
|
||||
#include <qwt_matrix_raster_data.h>
|
||||
#include <algorithm>
|
||||
#include <QFile>
|
||||
#include <QFormLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QSet>
|
||||
#include "BusyIndicator.h"
|
||||
#include <QTextStream>
|
||||
#include <QThread>
|
||||
#include <QVBoxLayout>
|
||||
#include <QwtInterval>
|
||||
#include <QwtLegend>
|
||||
#include <QwtLinearColorMap>
|
||||
#include <QwtMatrixRasterData>
|
||||
#include <QwtPlotCanvas>
|
||||
#include <QwtPlotSpectrogram>
|
||||
#include <QwtText>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <qwt_matrix_raster_data.h>
|
||||
|
||||
class HeatMapColorMap : public QwtLinearColorMap
|
||||
{
|
||||
class HeatMapColorMap : public QwtLinearColorMap {
|
||||
public:
|
||||
HeatMapColorMap() : QwtLinearColorMap(Qt::blue, Qt::red)
|
||||
HeatMapColorMap()
|
||||
: QwtLinearColorMap(Qt::blue, Qt::red)
|
||||
{
|
||||
addColorStop(0.25, Qt::cyan);
|
||||
addColorStop(0.5, Qt::green);
|
||||
|
|
@ -37,9 +37,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
TwoDSpectralCompliance::TwoDSpectralCompliance(QWidget *parent) :
|
||||
MeasureAnalysisView(parent),
|
||||
ui(new Ui::TwoDSpectralCompliance)
|
||||
TwoDSpectralCompliance::TwoDSpectralCompliance(QWidget* parent)
|
||||
: MeasureAnalysisView(parent)
|
||||
, ui(new Ui::TwoDSpectralCompliance)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
|
|
@ -49,7 +49,6 @@ TwoDSpectralCompliance::TwoDSpectralCompliance(QWidget *parent) :
|
|||
setupPlot();
|
||||
createFloatingInfoWidget();
|
||||
_busy_indicator = new BusyIndicator(this);
|
||||
|
||||
}
|
||||
|
||||
TwoDSpectralCompliance::~TwoDSpectralCompliance()
|
||||
|
|
@ -57,30 +56,29 @@ TwoDSpectralCompliance::~TwoDSpectralCompliance()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void TwoDSpectralCompliance::InitViewWorkspace(const QString &project_name)
|
||||
void TwoDSpectralCompliance::InitViewWorkspace(const QString& project_name)
|
||||
{
|
||||
Q_UNUSED(project_name);
|
||||
}
|
||||
|
||||
void TwoDSpectralCompliance::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||
void TwoDSpectralCompliance::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
||||
{
|
||||
if (data_files_set.isEmpty())
|
||||
return;
|
||||
QString csvFile = data_files_set.first().toString();
|
||||
if (csvFile.isEmpty())
|
||||
return;
|
||||
auto functionToRun = [this, csvFile](){
|
||||
_busy_indicator->Start();
|
||||
readCsv(csvFile);
|
||||
generateSurfaceData();
|
||||
updateSpectrogram();
|
||||
_busy_indicator->Stop();
|
||||
auto functionToRun = [this, csvFile]() {
|
||||
_busy_indicator->Start();
|
||||
readCsv(csvFile);
|
||||
generateSurfaceData();
|
||||
updateSpectrogram();
|
||||
_busy_indicator->Stop();
|
||||
};
|
||||
QThread* load_data_thread = QThread::create(functionToRun);
|
||||
load_data_thread->start();
|
||||
}
|
||||
|
||||
|
||||
void TwoDSpectralCompliance::setupPlot()
|
||||
{
|
||||
_plot->setCanvasBackground(Qt::white);
|
||||
|
|
@ -115,7 +113,7 @@ void TwoDSpectralCompliance::setupPlot()
|
|||
_spectrogram->attach(_plot);
|
||||
}
|
||||
|
||||
void TwoDSpectralCompliance::readCsv(const QString &filename)
|
||||
void TwoDSpectralCompliance::readCsv(const QString& filename)
|
||||
{
|
||||
m_rawData.clear();
|
||||
QFile file(filename);
|
||||
|
|
@ -183,64 +181,65 @@ void TwoDSpectralCompliance::generateSurfaceData()
|
|||
point.count = it.value();
|
||||
m_surfaceData.append(point);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TwoDSpectralCompliance::updateSpectrogram()
|
||||
{
|
||||
if (m_surfaceData.isEmpty()) {
|
||||
_spectrogram->setData(new QwtMatrixRasterData());
|
||||
_plot->replot();
|
||||
return;
|
||||
}
|
||||
|
||||
float minPrim = 1e9f, maxPrim = -1e9f;
|
||||
float minSec = 1e9f, maxSec = -1e9f;
|
||||
int maxCount = 0;
|
||||
|
||||
for (const auto& pt : m_surfaceData) {
|
||||
minPrim = std::min(minPrim, pt.primaryEnergy);
|
||||
maxPrim = std::max(maxPrim, pt.primaryEnergy);
|
||||
minSec = std::min(minSec, pt.secondaryEnergySum);
|
||||
maxSec = std::max(maxSec, pt.secondaryEnergySum);
|
||||
maxCount = std::max(maxCount, pt.count);
|
||||
}
|
||||
|
||||
double primRange = maxPrim - minPrim;
|
||||
double secRange = maxSec - minSec;
|
||||
if (primRange < 1e-6) primRange = 1.0;
|
||||
if (secRange < 1e-6) secRange = 1.0;
|
||||
double primStart = minPrim - primRange * 0.05;
|
||||
double primEnd = maxPrim + primRange * 0.05;
|
||||
double secStart = minSec - secRange * 0.05;
|
||||
double secEnd = maxSec + secRange * 0.05;
|
||||
|
||||
const int numCols = 200;
|
||||
const int numRows = 200;
|
||||
|
||||
double stepX = (primEnd - primStart) / numCols;
|
||||
double stepY = (secEnd - secStart) / numRows;
|
||||
|
||||
QVector<double> zValues(numRows * numCols, 0.0);
|
||||
|
||||
for (const auto& pt : m_surfaceData) {
|
||||
int col = static_cast<int>((pt.primaryEnergy - primStart) / stepX);
|
||||
int row = static_cast<int>((pt.secondaryEnergySum - secStart) / stepY);
|
||||
col = qBound(0, col, numCols - 1);
|
||||
row = qBound(0, row, numRows - 1);
|
||||
zValues[row * numCols + col] += pt.count;
|
||||
}
|
||||
|
||||
QwtMatrixRasterData* data = new QwtMatrixRasterData();
|
||||
data->setInterval(Qt::XAxis, QwtInterval(primStart, primEnd));
|
||||
data->setInterval(Qt::YAxis, QwtInterval(secStart, secEnd));
|
||||
data->setInterval(Qt::ZAxis, QwtInterval(0, maxCount));
|
||||
data->setValueMatrix(zValues, numCols);
|
||||
|
||||
_spectrogram->setData(data);
|
||||
_plot->setAxisScale(QwtPlot::xBottom, primStart, primEnd);
|
||||
_plot->setAxisScale(QwtPlot::yLeft, secStart, secEnd);
|
||||
_spectrogram->setData(new QwtMatrixRasterData());
|
||||
_plot->replot();
|
||||
return;
|
||||
}
|
||||
|
||||
float minPrim = 1e9f, maxPrim = -1e9f;
|
||||
float minSec = 1e9f, maxSec = -1e9f;
|
||||
int maxCount = 0;
|
||||
|
||||
for (const auto& pt : m_surfaceData) {
|
||||
minPrim = std::min(minPrim, pt.primaryEnergy);
|
||||
maxPrim = std::max(maxPrim, pt.primaryEnergy);
|
||||
minSec = std::min(minSec, pt.secondaryEnergySum);
|
||||
maxSec = std::max(maxSec, pt.secondaryEnergySum);
|
||||
maxCount = std::max(maxCount, pt.count);
|
||||
}
|
||||
|
||||
double primRange = maxPrim - minPrim;
|
||||
double secRange = maxSec - minSec;
|
||||
if (primRange < 1e-6)
|
||||
primRange = 1.0;
|
||||
if (secRange < 1e-6)
|
||||
secRange = 1.0;
|
||||
double primStart = minPrim - primRange * 0.05;
|
||||
double primEnd = maxPrim + primRange * 0.05;
|
||||
double secStart = minSec - secRange * 0.05;
|
||||
double secEnd = maxSec + secRange * 0.05;
|
||||
|
||||
const int numCols = 200;
|
||||
const int numRows = 200;
|
||||
|
||||
double stepX = (primEnd - primStart) / numCols;
|
||||
double stepY = (secEnd - secStart) / numRows;
|
||||
|
||||
QVector<double> zValues(numRows * numCols, 0.0);
|
||||
|
||||
for (const auto& pt : m_surfaceData) {
|
||||
int col = static_cast<int>((pt.primaryEnergy - primStart) / stepX);
|
||||
int row = static_cast<int>((pt.secondaryEnergySum - secStart) / stepY);
|
||||
col = qBound(0, col, numCols - 1);
|
||||
row = qBound(0, row, numRows - 1);
|
||||
zValues[row * numCols + col] += pt.count;
|
||||
}
|
||||
|
||||
QwtMatrixRasterData* data = new QwtMatrixRasterData();
|
||||
data->setInterval(Qt::XAxis, QwtInterval(primStart, primEnd));
|
||||
data->setInterval(Qt::YAxis, QwtInterval(secStart, secEnd));
|
||||
data->setInterval(Qt::ZAxis, QwtInterval(0, maxCount));
|
||||
data->setValueMatrix(zValues, numCols);
|
||||
|
||||
_spectrogram->setData(data);
|
||||
_plot->setAxisScale(QwtPlot::xBottom, primStart, primEnd);
|
||||
_plot->setAxisScale(QwtPlot::yLeft, secStart, secEnd);
|
||||
_plot->replot();
|
||||
}
|
||||
void TwoDSpectralCompliance::createFloatingInfoWidget()
|
||||
{
|
||||
|
|
@ -252,8 +251,7 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
|||
" background-color: rgba(240, 240, 240, 240);"
|
||||
" border: 1px solid gray;"
|
||||
" border-radius: 5px;"
|
||||
"}"
|
||||
);
|
||||
"}");
|
||||
m_floatingWidget->setFixedSize(320, 220);
|
||||
m_floatingWidget->setAttribute(Qt::WA_TranslucentBackground, false);
|
||||
|
||||
|
|
@ -324,17 +322,16 @@ void TwoDSpectralCompliance::createFloatingInfoWidget()
|
|||
" border-radius: 14px;"
|
||||
" font-weight: bold;"
|
||||
"}"
|
||||
"QPushButton:hover { background-color: rgba(150,150,150,200); }"
|
||||
);
|
||||
"QPushButton:hover { background-color: rgba(150,150,150,200); }");
|
||||
m_showButton->setText(QStringLiteral(u"⊕"));
|
||||
connect(m_showButton, &QPushButton::clicked, this, &TwoDSpectralCompliance::showFloatingWidget);
|
||||
|
||||
m_floatingWidget->move(10, 10);
|
||||
updateShowButtonPosition();
|
||||
m_floatingWidget->hide();
|
||||
m_showButton->show();
|
||||
m_floatingWidget->hide();
|
||||
m_showButton->show();
|
||||
|
||||
// m_floatingWidget->raise();
|
||||
// m_floatingWidget->raise();
|
||||
updateInfoContent();
|
||||
}
|
||||
|
||||
|
|
@ -399,7 +396,7 @@ void TwoDSpectralCompliance::updateInfoContent()
|
|||
m_secRangeEdit->setText(QString("[%1, %2]").arg(minSec, 0, 'f', 2).arg(maxSec, 0, 'f', 2));
|
||||
}
|
||||
|
||||
void TwoDSpectralCompliance::resizeEvent(QResizeEvent *event)
|
||||
void TwoDSpectralCompliance::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
updateShowButtonPosition();
|
||||
|
|
@ -414,11 +411,11 @@ void TwoDSpectralCompliance::resizeEvent(QResizeEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
bool TwoDSpectralCompliance::eventFilter(QObject *obj, QEvent *event)
|
||||
bool TwoDSpectralCompliance::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
if (obj == m_floatingWidget) {
|
||||
if (event->type() == QEvent::MouseButtonPress) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::LeftButton) {
|
||||
m_dragging = true;
|
||||
m_dragPosition = mouseEvent->globalPos() - m_floatingWidget->frameGeometry().topLeft();
|
||||
|
|
@ -427,7 +424,7 @@ bool TwoDSpectralCompliance::eventFilter(QObject *obj, QEvent *event)
|
|||
}
|
||||
} else if (event->type() == QEvent::MouseMove) {
|
||||
if (m_dragging) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
m_floatingWidget->move(mouseEvent->globalPos() - m_dragPosition);
|
||||
event->accept();
|
||||
return true;
|
||||
|
|
@ -443,11 +440,11 @@ bool TwoDSpectralCompliance::eventFilter(QObject *obj, QEvent *event)
|
|||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void TwoDSpectralCompliance::showEvent(QShowEvent *e)
|
||||
void TwoDSpectralCompliance::showEvent(QShowEvent* e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
if (_busy_indicator) {
|
||||
_busy_indicator->setGeometry(this->rect());
|
||||
this->update();
|
||||
}
|
||||
if (_busy_indicator) {
|
||||
_busy_indicator->setGeometry(this->rect());
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef TWODSPECTRALCOMPLIANCE_H
|
||||
#define TWODSPECTRALCOMPLIANCE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <MeasureAnalysisView.h>
|
||||
#include <QVector>
|
||||
#include <QPoint>
|
||||
#include <QVector>
|
||||
#include <QWidget>
|
||||
|
||||
class CustomQwtPlot;
|
||||
class QwtPlotSpectrogram;
|
||||
|
|
@ -22,19 +22,19 @@ struct TwoSurfacePoint {
|
|||
int count;
|
||||
};
|
||||
|
||||
class TwoDSpectralCompliance : public MeasureAnalysisView
|
||||
{
|
||||
class TwoDSpectralCompliance : public MeasureAnalysisView {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TwoDSpectralCompliance(QWidget *parent = nullptr);
|
||||
explicit TwoDSpectralCompliance(QWidget* parent = nullptr);
|
||||
~TwoDSpectralCompliance();
|
||||
|
||||
virtual void InitViewWorkspace(const QString& project_name) override final;
|
||||
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set) override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
virtual void showEvent(QShowEvent* e) override final;
|
||||
|
||||
private:
|
||||
|
|
@ -54,9 +54,8 @@ private slots:
|
|||
void showFloatingWidget();
|
||||
void hideFloatingWidget();
|
||||
|
||||
|
||||
private:
|
||||
Ui::TwoDSpectralCompliance *ui;
|
||||
Ui::TwoDSpectralCompliance* ui;
|
||||
CustomQwtPlot* _plot = nullptr;
|
||||
QwtPlotSpectrogram* _spectrogram = nullptr;
|
||||
|
||||
|
|
@ -70,20 +69,19 @@ private:
|
|||
QVector<EventData> m_rawData;
|
||||
QVector<TwoSurfacePoint> m_surfaceData;
|
||||
|
||||
QWidget* m_floatingWidget = nullptr;
|
||||
QPushButton* m_toggleButton = nullptr;
|
||||
QPushButton* m_showButton = nullptr;
|
||||
QWidget* m_floatingWidget = nullptr;
|
||||
QPushButton* m_toggleButton = nullptr;
|
||||
QPushButton* m_showButton = nullptr;
|
||||
|
||||
QLineEdit* m_totalEventsEdit = nullptr;
|
||||
QLineEdit* m_totalPointsEdit = nullptr;
|
||||
QLineEdit* m_maxCountEdit = nullptr;
|
||||
QLineEdit* m_primRangeEdit = nullptr;
|
||||
QLineEdit* m_secRangeEdit = nullptr;
|
||||
|
||||
QPoint m_dragPosition;
|
||||
bool m_dragging = false;
|
||||
BusyIndicator* _busy_indicator = nullptr;
|
||||
QLineEdit* m_totalEventsEdit = nullptr;
|
||||
QLineEdit* m_totalPointsEdit = nullptr;
|
||||
QLineEdit* m_maxCountEdit = nullptr;
|
||||
QLineEdit* m_primRangeEdit = nullptr;
|
||||
QLineEdit* m_secRangeEdit = nullptr;
|
||||
|
||||
QPoint m_dragPosition;
|
||||
bool m_dragging = false;
|
||||
BusyIndicator* _busy_indicator = nullptr;
|
||||
};
|
||||
|
||||
#endif // TWODSPECTRALCOMPLIANCE_H
|
||||
|
|
|
|||
|
|
@ -1,33 +1,36 @@
|
|||
#include "AntiConformEnergySpectrumView.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QwtPlotCurve>
|
||||
#include <QwtPlotCanvas>
|
||||
#include <QwtText>
|
||||
#include "CustomQwtPlot.h"
|
||||
#include <GlobalDefine.h>
|
||||
#include "csv.h"
|
||||
#include <QFileInfo>
|
||||
#include <QThread>
|
||||
#include "BusyIndicator.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "CustomQwtPlot.h"
|
||||
#include "csv.h"
|
||||
#include <GlobalDefine.h>
|
||||
#include <QFileInfo>
|
||||
#include <QMenu>
|
||||
#include <QPen>
|
||||
#include <QThread>
|
||||
#include <QVBoxLayout>
|
||||
#include <QwtPlotCanvas>
|
||||
#include <QwtPlotCurve>
|
||||
#include <QwtText>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <QPen>
|
||||
struct SpectrumData
|
||||
{
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
struct SpectrumData {
|
||||
int board_id;
|
||||
int channel_id;
|
||||
double energy;
|
||||
uint64_t timestamp;
|
||||
};
|
||||
|
||||
|
||||
AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget *parent) :
|
||||
MeasureAnalysisView(parent)
|
||||
AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget* parent)
|
||||
: MeasureAnalysisView(parent)
|
||||
{
|
||||
this->setViewType(PlotFrame);
|
||||
|
||||
this->_menu = new QMenu(this);
|
||||
setupMenu();
|
||||
|
||||
_plot = new CustomQwtPlot();
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(_plot);
|
||||
|
|
@ -50,6 +53,7 @@ AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget *parent) :
|
|||
_plot->enableAxis(QwtPlot::xBottom);
|
||||
_plot->enableAxis(QwtPlot::yLeft);
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
_plot->SetAxisDragScale(QwtPlot::yLeft, true);
|
||||
|
||||
_curve = new QwtPlotCurve();
|
||||
_curve->setStyle(QwtPlotCurve::Lines);
|
||||
|
|
@ -63,12 +67,12 @@ AntiConformEnergySpectrumView::~AntiConformEnergySpectrumView()
|
|||
{
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::InitViewWorkspace(const QString &project_name)
|
||||
void AntiConformEnergySpectrumView::InitViewWorkspace(const QString& project_name)
|
||||
{
|
||||
Q_UNUSED(project_name);
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||
void AntiConformEnergySpectrumView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
||||
{
|
||||
const QString& data_filename = data_files_set.first().toString();
|
||||
if (!data_filename.isEmpty() && QFileInfo(data_filename).exists()) {
|
||||
|
|
@ -77,21 +81,21 @@ void AntiConformEnergySpectrumView::SetAnalyzeDataFilename(const QMap<QString, Q
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void AntiConformEnergySpectrumView::loadAndProcess()
|
||||
{
|
||||
auto functionToRun = [this]() {
|
||||
if (_data_filename.isEmpty()) return;
|
||||
if (_data_filename.isEmpty())
|
||||
return;
|
||||
|
||||
_busy_indicator->Start();
|
||||
|
||||
std::vector<SpectrumData> rawData;
|
||||
io::CSVReader<4> in(QStrToSysPath(_data_filename));
|
||||
in.read_header(io::ignore_extra_column,
|
||||
QString(QStringLiteral(u"板卡号")).toStdString(),
|
||||
QString(QStringLiteral(u"通道号")).toStdString(),
|
||||
QString(QStringLiteral(u"能量(KeV)")).toStdString(),
|
||||
QString(QStringLiteral(u"时间计数")).toStdString());
|
||||
QString(QStringLiteral(u"板卡号")).toStdString(),
|
||||
QString(QStringLiteral(u"通道号")).toStdString(),
|
||||
QString(QStringLiteral(u"能量(KeV)")).toStdString(),
|
||||
QString(QStringLiteral(u"时间计数")).toStdString());
|
||||
|
||||
int board, channel;
|
||||
double energy;
|
||||
|
|
@ -134,19 +138,21 @@ void AntiConformEnergySpectrumView::loadAndProcess()
|
|||
|
||||
QMetaObject::invokeMethod(this, [this, vx, vy, dmaxx, dmaxy]() {
|
||||
_curve->setSamples(vx, vy);
|
||||
|
||||
_plot->setAxisScale(QwtPlot::xBottom, 0, dmaxx);
|
||||
_plot->setAxisScale(QwtPlot::yLeft, 0, dmaxy * 1.1);
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, dmaxx);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, dmaxy);
|
||||
_plot->replot();
|
||||
_busy_indicator->Stop();
|
||||
}, Qt::QueuedConnection);
|
||||
_busy_indicator->Stop(); }, Qt::QueuedConnection);
|
||||
};
|
||||
|
||||
QThread* load_thread = QThread::create(functionToRun);
|
||||
load_thread->start();
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::showEvent(QShowEvent *e)
|
||||
void AntiConformEnergySpectrumView::onActionPlotConfigure()
|
||||
{
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::showEvent(QShowEvent* e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
if (_busy_indicator) {
|
||||
|
|
@ -155,4 +161,19 @@ void AntiConformEnergySpectrumView::showEvent(QShowEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void AntiConformEnergySpectrumView::setupMenu()
|
||||
{
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &AntiConformEnergySpectrumView::customContextMenuRequested, [this](const QPoint& pos) {
|
||||
this->_menu->exec(this->mapToGlobal(pos));
|
||||
});
|
||||
QAction* action_plot_reset = this->_menu->addAction(QStringLiteral(u"还原"));
|
||||
action_plot_reset->setObjectName("plot_reset");
|
||||
connect(action_plot_reset, &QAction::triggered, [this]() {
|
||||
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, &AntiConformEnergySpectrumView::onActionPlotConfigure);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
#include "MeasureAnalysisView.h"
|
||||
|
||||
class QMenu;
|
||||
class CustomQwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class BusyIndicator;
|
||||
|
||||
class AntiConformEnergySpectrumView : public MeasureAnalysisView
|
||||
{
|
||||
class AntiConformEnergySpectrumView : public MeasureAnalysisView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AntiConformEnergySpectrumView(QWidget *parent = nullptr);
|
||||
explicit AntiConformEnergySpectrumView(QWidget* parent = nullptr);
|
||||
virtual ~AntiConformEnergySpectrumView();
|
||||
virtual void InitViewWorkspace(const QString& project_name) override final;
|
||||
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set) override;
|
||||
|
|
@ -20,9 +20,14 @@ protected:
|
|||
virtual void showEvent(QShowEvent* e) override final;
|
||||
|
||||
private:
|
||||
void loadAndProcess(); // 读取CSV,执行符合处理,绘制能谱折线图
|
||||
void setupMenu();
|
||||
void loadAndProcess(); // 读取CSV,执行符合处理,绘制能谱折线图
|
||||
|
||||
private slots:
|
||||
void onActionPlotConfigure();
|
||||
|
||||
private:
|
||||
QMenu* _menu = nullptr;
|
||||
BusyIndicator* _busy_indicator = nullptr;
|
||||
CustomQwtPlot* _plot = nullptr;
|
||||
QwtPlotCurve* _curve = nullptr;
|
||||
|
|
@ -30,5 +35,3 @@ private:
|
|||
};
|
||||
|
||||
#endif // ANTICONFORMENERGYSPECTRUMVIEW_H
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <QPen>
|
||||
#include <QMenu>
|
||||
|
||||
struct SpectrumData
|
||||
{
|
||||
int board_id;
|
||||
|
|
@ -28,6 +30,9 @@ ConformToTheEnergySpectrum::ConformToTheEnergySpectrum(QWidget *parent) :
|
|||
{
|
||||
this->setViewType(PlotFrame);
|
||||
|
||||
this->_menu = new QMenu(this);
|
||||
setupMenu();
|
||||
|
||||
_plot = new CustomQwtPlot();
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(_plot);
|
||||
|
|
@ -50,6 +55,7 @@ ConformToTheEnergySpectrum::ConformToTheEnergySpectrum(QWidget *parent) :
|
|||
_plot->enableAxis(QwtPlot::xBottom);
|
||||
_plot->enableAxis(QwtPlot::yLeft);
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
_plot->SetAxisDragScale(QwtPlot::yLeft, true);
|
||||
|
||||
_curve = new QwtPlotCurve();
|
||||
_curve->setStyle(QwtPlotCurve::Lines);
|
||||
|
|
@ -154,9 +160,8 @@ void ConformToTheEnergySpectrum::loadAndProcess()
|
|||
|
||||
QMetaObject::invokeMethod(this, [this, vx, vy, dmaxx, dmaxy]() {
|
||||
_curve->setSamples(vx, vy);
|
||||
|
||||
_plot->setAxisScale(QwtPlot::xBottom, 0, dmaxx);
|
||||
_plot->setAxisScale(QwtPlot::yLeft, 0, dmaxy * 1.1);
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, dmaxx);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, dmaxy);
|
||||
_plot->replot();
|
||||
_busy_indicator->Stop();
|
||||
}, Qt::QueuedConnection);
|
||||
|
|
@ -166,6 +171,11 @@ void ConformToTheEnergySpectrum::loadAndProcess()
|
|||
load_thread->start();
|
||||
}
|
||||
|
||||
void ConformToTheEnergySpectrum::onActionPlotConfigure()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ConformToTheEnergySpectrum::showEvent(QShowEvent *e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
|
|
@ -175,4 +185,22 @@ void ConformToTheEnergySpectrum::showEvent(QShowEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
void ConformToTheEnergySpectrum::setupMenu()
|
||||
{
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &ConformToTheEnergySpectrum::customContextMenuRequested, [this](const QPoint& pos) {
|
||||
this->_menu->exec(this->mapToGlobal(pos));
|
||||
});
|
||||
QAction* action_plot_reset = this->_menu->addAction(QStringLiteral(u"还原"));
|
||||
action_plot_reset->setObjectName("plot_reset");
|
||||
connect(action_plot_reset, &QAction::triggered, [this]() {
|
||||
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, &ConformToTheEnergySpectrum::onActionPlotConfigure);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "MeasureAnalysisView.h"
|
||||
|
||||
class QMenu;
|
||||
class CustomQwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class BusyIndicator;
|
||||
|
|
@ -20,9 +21,14 @@ protected:
|
|||
virtual void showEvent(QShowEvent* e) override final;
|
||||
|
||||
private:
|
||||
void setupMenu();
|
||||
void loadAndProcess(); // 读取CSV,执行符合处理,绘制能谱折线图
|
||||
|
||||
private slots:
|
||||
void onActionPlotConfigure();
|
||||
|
||||
private:
|
||||
QMenu* _menu = nullptr;
|
||||
BusyIndicator* _busy_indicator = nullptr;
|
||||
CustomQwtPlot* _plot = nullptr;
|
||||
QwtPlotCurve* _curve = nullptr;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "csv.h"
|
||||
#include <QThread>
|
||||
#include "BusyIndicator.h"
|
||||
#include <QMenu>
|
||||
|
||||
CountRateAnalysisView::CountRateAnalysisView(QWidget *parent) :
|
||||
MeasureAnalysisView(parent),
|
||||
|
|
@ -25,9 +26,11 @@ CountRateAnalysisView::CountRateAnalysisView(QWidget *parent) :
|
|||
ui->setupUi(this);
|
||||
this->setViewType(PlotFrame);
|
||||
|
||||
InitUi();
|
||||
this->_menu = new QMenu(this);
|
||||
_busy_indicator = new BusyIndicator(this);
|
||||
|
||||
InitUi();
|
||||
setupMenu();
|
||||
}
|
||||
|
||||
CountRateAnalysisView::~CountRateAnalysisView()
|
||||
|
|
@ -82,20 +85,26 @@ void CountRateAnalysisView::setData(QVector<ParticleInjectTime> data)
|
|||
QVector<double> vec(nVecSize); // 默认初始化为0
|
||||
|
||||
|
||||
double minValue = 0;
|
||||
double maxValue = 0;
|
||||
for(auto info : data)
|
||||
{
|
||||
double x_max = 0;
|
||||
double y_max = 0;
|
||||
for(auto info : data) {
|
||||
const qint64 ns = (info.dTime * 5) / NS_PER_SECOND;
|
||||
const int nidx = static_cast<int>(ns / nInv); // 整数除法,速度快
|
||||
if (nidx < nVecSize)
|
||||
++vec[nidx]; // 使用 ++ 而非 vec[nidx]++
|
||||
if (nidx < nVecSize) {
|
||||
++vec[nidx]; // 使用 ++ 而非 vec[nidx]++
|
||||
if ( y_max < vec[nidx] )
|
||||
y_max = vec[nidx];
|
||||
}
|
||||
}
|
||||
|
||||
QVector<double> vecXpt(vec.size());
|
||||
for (int i = 0; i < vec.size(); ++i)
|
||||
for (int i = 0; i < vec.size(); ++i) {
|
||||
vecXpt[i] = static_cast<double>(i);
|
||||
|
||||
if ( x_max < vecXpt[i] )
|
||||
x_max = vecXpt[i];
|
||||
}
|
||||
plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max);
|
||||
plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max);
|
||||
// 创建曲线并设置数据
|
||||
QwtPlotCurve *curve = new QwtPlotCurve();
|
||||
curve->setSamples(vecXpt, vec);
|
||||
|
|
@ -170,3 +179,26 @@ void CountRateAnalysisView::setupPlot()
|
|||
|
||||
plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
}
|
||||
|
||||
void CountRateAnalysisView::setupMenu()
|
||||
{
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &CountRateAnalysisView::customContextMenuRequested, [this](const QPoint& pos) {
|
||||
this->_menu->exec(this->mapToGlobal(pos));
|
||||
});
|
||||
QAction* action_plot_reset = this->_menu->addAction(QStringLiteral(u"还原"));
|
||||
action_plot_reset->setObjectName("plot_reset");
|
||||
connect(action_plot_reset, &QAction::triggered, [this]() {
|
||||
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, &CountRateAnalysisView::onActionPlotConfigure);
|
||||
|
||||
}
|
||||
|
||||
void CountRateAnalysisView::onActionPlotConfigure()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
class CustomQwtPlot;
|
||||
class BusyIndicator;
|
||||
|
||||
class QMenu;
|
||||
|
||||
namespace Ui {
|
||||
class CountRateAnalysisView;
|
||||
|
|
@ -34,11 +34,16 @@ protected:
|
|||
private:
|
||||
void InitUi();
|
||||
void setupPlot();
|
||||
void setupMenu();
|
||||
|
||||
private slots:
|
||||
void onActionPlotConfigure();
|
||||
|
||||
private:
|
||||
Ui::CountRateAnalysisView *ui;
|
||||
BusyIndicator* _busy_indicator = nullptr;
|
||||
CustomQwtPlot *plot;
|
||||
QMenu* _menu = nullptr;
|
||||
QVector<ParticleInjectTime> m_AllData;//存储的所有的粒子入射时间数据
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ void EnergyCountPeakFitView::setupPlot()
|
|||
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));
|
||||
|
|
@ -269,10 +270,18 @@ void EnergyCountPeakFitView::loadDataFromFile(const QString& data_name, const QS
|
|||
double energy;
|
||||
unsigned long long energy_count;
|
||||
QVector<double> x, y;
|
||||
double x_max = 0.0f, y_max = 0.0f;
|
||||
while (reader.read_row(energy, energy_count)) {
|
||||
x.push_back(energy);
|
||||
y.push_back(energy_count);
|
||||
if ( x_max < energy )
|
||||
x_max = energy;
|
||||
if ( y_max < energy_count )
|
||||
y_max = energy_count;
|
||||
}
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max);
|
||||
|
||||
// 绘制曲线
|
||||
QwtPlotCurve* curve = new QwtPlotCurve(QStringLiteral(u"原始数据"));
|
||||
curve->setPen(QPen(Qt::gray, 2)); // 原始数据统一灰色
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ void EnergyCountPlotView::setupPlot()
|
|||
_plot->insertLegend(legend, QwtPlot::RightLegend);
|
||||
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
_plot->SetAxisDragScale(QwtPlot::yLeft, true);
|
||||
|
||||
_data_selector = new CustomQwtPlotXaxisSelector(_plot->canvas());
|
||||
_data_selector->setEnabled(false);
|
||||
}
|
||||
|
|
@ -127,7 +129,14 @@ void EnergyCountPlotView::loadDataFromFile(const QString &data_name, const QStri
|
|||
while (reader.read_row(energy, energy_count)) {
|
||||
x.push_back(energy);
|
||||
y.push_back(energy_count);
|
||||
if ( _x_max < energy )
|
||||
_x_max = energy;
|
||||
if ( _y_max < energy_count )
|
||||
_y_max = energy_count;
|
||||
}
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, _x_max);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, _y_max);
|
||||
|
||||
// 绘制曲线
|
||||
QwtPlotCurve* curve = new QwtPlotCurve(data_name);
|
||||
curve->setSamples(x, y);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ private:
|
|||
QMenu* _menu = nullptr;
|
||||
QDialog* _curve_show_setting_dlg = nullptr;
|
||||
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
|
||||
double _x_max = 0.0f;
|
||||
double _y_max = 0.0f;
|
||||
};
|
||||
|
||||
#endif // ENERGYCOUNTPLOTVIEW_H
|
||||
|
|
|
|||
|
|
@ -1,191 +1,220 @@
|
|||
#include "MeasureClient.h"
|
||||
#include "MeasureServiceProtocol.h"
|
||||
#include <QByteArray>
|
||||
#include <QTimer>
|
||||
#include <QJsonDocument>
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
|
||||
MeasureClient::MeasureClient(QObject *parent) : QObject(parent)
|
||||
MeasureClient::MeasureClient(QObject *parent)
|
||||
: QObject(parent),
|
||||
_is_auto_reconnect(true),
|
||||
_response_buffer(new QByteArray()),
|
||||
_response_data_len(0)
|
||||
{
|
||||
_host = "127.0.0.1";
|
||||
_port = 9999;
|
||||
|
||||
// 创建工作线程
|
||||
_workerThread = new QThread(this);
|
||||
this->moveToThread(_workerThread);
|
||||
_workerThread->start();
|
||||
|
||||
_tcp_socket = new QTcpSocket(this);
|
||||
_reconnect_timer = new QTimer(this);
|
||||
|
||||
connect(_tcp_socket, &QTcpSocket::connected, this, &MeasureClient::onConnected);
|
||||
connect(_tcp_socket, &QTcpSocket::disconnected, this, &MeasureClient::onDisconnected);
|
||||
connect(_tcp_socket, &QTcpSocket::readyRead, this, &MeasureClient::onReadyRead);
|
||||
connect(_tcp_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &MeasureClient::onSocketError);
|
||||
connect(_reconnect_timer, &QTimer::timeout, this, &MeasureClient::tryReconnect);
|
||||
_reconnect_timer->setInterval(300);
|
||||
}
|
||||
|
||||
MeasureClient::~MeasureClient()
|
||||
{
|
||||
if (_workerThread->isRunning()) {
|
||||
_workerThread->quit();
|
||||
_workerThread->wait();
|
||||
if (_tcp_socket->isOpen()) {
|
||||
_tcp_socket->close();
|
||||
}
|
||||
delete _workerThread;
|
||||
}
|
||||
|
||||
void MeasureClient::setServerAddress(const QString &host, quint16 port)
|
||||
void MeasureClient::connectToServer(const QString &ip, quint16 port)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
_host = host;
|
||||
_host = ip;
|
||||
_port = port;
|
||||
_tcp_socket->connectToHost(_host, _port);
|
||||
}
|
||||
|
||||
void MeasureClient::startMeasure(const QString &deviceGuid, const QVariantMap &config)
|
||||
void MeasureClient::disconnectFromServer()
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processCommand", Qt::QueuedConnection,
|
||||
Q_ARG(QString, "START"),
|
||||
Q_ARG(QString, deviceGuid),
|
||||
Q_ARG(QVariantMap, config));
|
||||
_is_auto_reconnect = false;
|
||||
_reconnect_timer->stop();
|
||||
if (_tcp_socket->isOpen()) {
|
||||
_tcp_socket->disconnectFromHost();
|
||||
_tcp_socket->close();
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureClient::stopMeasure(const QString &deviceGuid)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processCommand", Qt::QueuedConnection,
|
||||
Q_ARG(QString, "STOP"),
|
||||
Q_ARG(QString, deviceGuid),
|
||||
Q_ARG(QVariantMap, QVariantMap()));
|
||||
}
|
||||
|
||||
void MeasureClient::setMeasureConfigParams(const QString &deviceGuid, const QVariantMap &config)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processCommand", Qt::QueuedConnection,
|
||||
Q_ARG(QString, "SET"),
|
||||
Q_ARG(QString, deviceGuid),
|
||||
Q_ARG(QVariantMap, config));
|
||||
}
|
||||
|
||||
void MeasureClient::clearData(const QString &deviceGuid)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processCommand", Qt::QueuedConnection,
|
||||
Q_ARG(QString, "CLEAR"),
|
||||
Q_ARG(QString, deviceGuid),
|
||||
Q_ARG(QVariantMap, QVariantMap()));
|
||||
}
|
||||
|
||||
void MeasureClient::getDeviceList()
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processCommand", Qt::QueuedConnection,
|
||||
Q_ARG(QString, "DEVICE"),
|
||||
Q_ARG(QString, ""),
|
||||
Q_ARG(QVariantMap, QVariantMap()));
|
||||
}
|
||||
|
||||
void MeasureClient::processCommand(const QString &command, const QString &device_guid, const QVariantMap &config)
|
||||
void MeasureClient::startMeasure(const QString &device_guid, const QVariantMap &config)
|
||||
{
|
||||
QString data;
|
||||
if (!config.isEmpty()) {
|
||||
QJsonDocument json_doc = QJsonDocument::fromVariant(config);
|
||||
data = json_doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
QVariantMap response = sendCommand(command, device_guid, data);
|
||||
|
||||
bool success = response["success"].toBool();
|
||||
QString message = response["message"].toString();
|
||||
|
||||
if (command == "START") {
|
||||
QString gvf_filename;
|
||||
if (success) {
|
||||
gvf_filename = response["devices"].toString();
|
||||
emit startMeasureResult(success, gvf_filename);
|
||||
} else {
|
||||
emit startMeasureResult(success, message);
|
||||
}
|
||||
} else if (command == "STOP") {
|
||||
emit stopMeasureResult(success, message);
|
||||
} else if (command == "SET") {
|
||||
emit setMeasureConfigParamsResult(success, message);
|
||||
} else if (command == "CLEAR") {
|
||||
emit clearDataResult(success, message);
|
||||
} else if (command == "DEVICE") {
|
||||
QStringList devices;
|
||||
if (success) {
|
||||
devices = response["devices"].toStringList();
|
||||
}
|
||||
emit getDeviceListResult(success, devices);
|
||||
} else {
|
||||
emit errorOccurred(message);
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap MeasureClient::sendCommand(const QString &command, const QString &device_guid, const QString &data)
|
||||
{
|
||||
QVariantMap result;
|
||||
result["success"] = false;
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
QString host = _host;
|
||||
quint16 port = _port;
|
||||
locker.unlock();
|
||||
|
||||
// 创建临时socket(短连接)
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(host, port);
|
||||
if (!socket.waitForConnected(3000)) {
|
||||
result["message"] = QStringLiteral(u"连接服务失败:") + socket.errorString();
|
||||
emit errorOccurred(result["message"].toString());
|
||||
return result;
|
||||
}
|
||||
// 发送命令
|
||||
QByteArray request_data;
|
||||
QDataStream request_stream(&request_data, QIODevice::WriteOnly);
|
||||
request_stream << command << device_guid;
|
||||
|
||||
request_stream << QString("START") << device_guid;
|
||||
if (!data.isEmpty()) {
|
||||
request_stream << data;
|
||||
}
|
||||
socket.write(request_data);
|
||||
if (!socket.waitForBytesWritten(1000)) {
|
||||
result["message"] = QStringLiteral(u"发送请求失败:") + socket.errorString();
|
||||
emit errorOccurred(result["message"].toString());
|
||||
socket.disconnectFromHost();
|
||||
return result;
|
||||
this->sendRequst(request_data);
|
||||
}
|
||||
|
||||
void MeasureClient::stopMeasure(const QString &device_guid)
|
||||
{
|
||||
QByteArray request_data;
|
||||
QDataStream request_stream(&request_data, QIODevice::WriteOnly);
|
||||
request_stream << QString("STOP") << device_guid;
|
||||
this->sendRequst(request_data);
|
||||
}
|
||||
|
||||
void MeasureClient::setMeasureConfigParams(const QString &device_guid, const QVariantMap &config)
|
||||
{
|
||||
QByteArray request_data;
|
||||
QDataStream request_stream(&request_data, QIODevice::WriteOnly);
|
||||
request_stream << QString("SET") << device_guid;
|
||||
this->sendRequst(request_data);
|
||||
}
|
||||
|
||||
void MeasureClient::clearData(const QString &device_guid)
|
||||
{
|
||||
QByteArray request_data;
|
||||
QDataStream request_stream(&request_data, QIODevice::WriteOnly);
|
||||
request_stream << QString("CLEAR") << device_guid;
|
||||
this->sendRequst(request_data);
|
||||
}
|
||||
|
||||
void MeasureClient::getDeviceList()
|
||||
{
|
||||
QByteArray request_data;
|
||||
QDataStream request_stream(&request_data, QIODevice::WriteOnly);
|
||||
request_stream << QString("DEVICE");
|
||||
this->sendRequst(request_data);
|
||||
}
|
||||
|
||||
void MeasureClient::onConnected()
|
||||
{
|
||||
_reconnect_timer->stop();
|
||||
emit runningInfo(QStringLiteral(u"连接到服务器"));
|
||||
}
|
||||
|
||||
void MeasureClient::onDisconnected()
|
||||
{
|
||||
if (_is_auto_reconnect) {
|
||||
emit runningInfo(QStringLiteral(u"重连服务器......"));
|
||||
_reconnect_timer->start();
|
||||
} else {
|
||||
emit runningInfo(QStringLiteral(u"断开服务器连接"));
|
||||
}
|
||||
// 等待响应
|
||||
if (!socket.waitForReadyRead(5000)) {
|
||||
result["message"] = QStringLiteral(u"服务无响应:") + socket.errorString();
|
||||
emit errorOccurred(result["message"].toString());
|
||||
socket.disconnectFromHost();
|
||||
return result;
|
||||
}
|
||||
|
||||
void MeasureClient::onReadyRead()
|
||||
{
|
||||
_response_buffer->append(_tcp_socket->readAll());
|
||||
while (true) {
|
||||
if (_response_data_len == 0) {
|
||||
if (_response_buffer->size() < Protocol::HEAD_SIZE) break;
|
||||
QByteArray head = _response_buffer->left(Protocol::HEAD_SIZE);
|
||||
_response_data_len = Protocol::UnpackDataLen(head);
|
||||
_response_buffer->remove(0, Protocol::HEAD_SIZE);
|
||||
}
|
||||
if (_response_buffer->size() >= _response_data_len) {
|
||||
QByteArray response_data = _response_buffer->left(_response_data_len);
|
||||
_response_buffer->remove(0, _response_data_len);
|
||||
QThread* process_thread = QThread::create(&MeasureClient::processResponse, this, response_data);
|
||||
connect(process_thread, &QThread::finished, process_thread, &QThread::deleteLater);
|
||||
process_thread->start();
|
||||
_response_data_len = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 读取响应
|
||||
QByteArray response_data = socket.readAll();
|
||||
QDataStream response_stream(&response_data, QIODevice::ReadOnly);
|
||||
|
||||
}
|
||||
|
||||
void MeasureClient::onSocketError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
emit errorOccurred(QStringLiteral(u"连接异常:%1").arg(_tcp_socket->errorString()));
|
||||
if (error == QAbstractSocket::ConnectionRefusedError) {
|
||||
_reconnect_timer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureClient::tryReconnect()
|
||||
{
|
||||
_tcp_socket->connectToHost(_host, _port);
|
||||
}
|
||||
|
||||
void MeasureClient::sendRequst(const QByteArray &data)
|
||||
{
|
||||
if (!_tcp_socket->isOpen()) {
|
||||
emit errorOccurred(QStringLiteral(u"未连接服务器,请求发送失败"));
|
||||
return;
|
||||
}
|
||||
QByteArray requst_buf = Protocol::PackData(data);
|
||||
_tcp_socket->write(requst_buf);
|
||||
_tcp_socket->flush();
|
||||
}
|
||||
|
||||
void MeasureClient::processResponse(const QByteArray &response_data)
|
||||
{
|
||||
QDataStream response_stream(response_data);
|
||||
QString response_command;
|
||||
bool success;
|
||||
response_stream >> response_command >> success;
|
||||
result["success"] = success;
|
||||
if (response_command == "DEVICE") {
|
||||
// 处理设备列表响应
|
||||
if (response_command == "GVF") {
|
||||
int data_size;
|
||||
response_stream >> data_size;
|
||||
QByteArray data_buf;
|
||||
data_buf.resize(data_size);
|
||||
response_stream.readRawData(data_buf.data(), data_size);
|
||||
emit gvfData(data_buf);
|
||||
} else if (response_command == "START") {
|
||||
if (success) {
|
||||
QString measure_gvf_data_filename;
|
||||
response_stream >> measure_gvf_data_filename;
|
||||
emit startMeasureResult(success, measure_gvf_data_filename);
|
||||
} else {
|
||||
QString message;
|
||||
response_stream >> message;
|
||||
emit startMeasureResult(success, message);
|
||||
}
|
||||
} else if (response_command == "DEVICE") {
|
||||
QStringList devices;
|
||||
QString message;
|
||||
if (success) {
|
||||
int count;
|
||||
response_stream >> count;
|
||||
QStringList devices;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
QString device;
|
||||
response_stream >> device;
|
||||
devices << device;
|
||||
}
|
||||
result["devices"] = devices;
|
||||
} else {
|
||||
response_stream >> message;
|
||||
}
|
||||
} else if ((response_command == "START") && success) {
|
||||
// 处理设备列表响应
|
||||
if (success) {
|
||||
QString measure_gvf_data_filename;
|
||||
response_stream >> measure_gvf_data_filename;
|
||||
result["gvf"] = measure_gvf_data_filename;
|
||||
}
|
||||
} else {
|
||||
// 处理其他响应
|
||||
emit getDeviceListResult(success, message, devices);
|
||||
} else if (response_command == "STOP") {
|
||||
QString message;
|
||||
response_stream >> message;
|
||||
result["message"] = message;
|
||||
emit stopMeasureResult(success, message);
|
||||
} else if (response_command == "SET") {
|
||||
QString message;
|
||||
response_stream >> message;
|
||||
emit setMeasureConfigParamsResult(success, message);
|
||||
} else if (response_command == "CLEAR") {
|
||||
QString message;
|
||||
response_stream >> message;
|
||||
emit clearDataResult(success, message);
|
||||
} else {
|
||||
QString message;
|
||||
response_stream >> message;
|
||||
emit errorOccurred(message);
|
||||
}
|
||||
|
||||
// 断开连接
|
||||
socket.disconnectFromHost();
|
||||
if (socket.state() != QTcpSocket::UnconnectedState) {
|
||||
socket.waitForDisconnected(1000);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
#define MEASURECLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTcpSocket>
|
||||
#include <QDataStream>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QVariantMap>
|
||||
#include <QVariantList>
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QTcpSocket>
|
||||
|
||||
class QByteArray;
|
||||
class QTimer;
|
||||
|
||||
class MeasureClient : public QObject
|
||||
{
|
||||
|
|
@ -19,42 +18,45 @@ public:
|
|||
explicit MeasureClient(QObject *parent = nullptr);
|
||||
~MeasureClient();
|
||||
|
||||
// 设置服务器地址和端口
|
||||
void setServerAddress(const QString &host, quint16 port);
|
||||
// 启动测量(异步)
|
||||
void startMeasure(const QString &deviceGuid, const QVariantMap &config);
|
||||
// 停止测量(异步)
|
||||
void stopMeasure(const QString &deviceGuid);
|
||||
// 设置测量参数(异步)
|
||||
void setMeasureConfigParams(const QString &deviceGuid, const QVariantMap &config);
|
||||
// 清除数据(异步)
|
||||
void clearData(const QString &deviceGuid);
|
||||
// 获取设备列表(异步)
|
||||
void connectToServer(const QString &ip = "127.0.0.1", quint16 port = 9999);
|
||||
void disconnectFromServer();
|
||||
void startMeasure(const QString &device_guid, const QVariantMap &config);
|
||||
void stopMeasure(const QString &device_guid);
|
||||
void setMeasureConfigParams(const QString &device_guid, const QVariantMap &config);
|
||||
void clearData(const QString &device_guid);
|
||||
void getDeviceList();
|
||||
|
||||
signals:
|
||||
// 操作结果信号
|
||||
void startMeasureResult(bool success, const QString &info);
|
||||
void stopMeasureResult(bool success, const QString &message);
|
||||
void setMeasureConfigParamsResult(bool success, const QString &message);
|
||||
void clearDataResult(bool success, const QString &message);
|
||||
void getDeviceListResult(bool success, const QStringList &devices);
|
||||
// 错误信号
|
||||
void errorOccurred(const QString &errorString);
|
||||
void getDeviceListResult(bool success, const QString &message, const QStringList &devices);
|
||||
void runningInfo(const QString &info);
|
||||
void errorOccurred(const QString &error);
|
||||
|
||||
void gvfData(const QByteArray& data);
|
||||
|
||||
private slots:
|
||||
// 处理命令执行
|
||||
void processCommand(const QString &command, const QString &device_guid, const QVariantMap &config);
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onReadyRead();
|
||||
void onSocketError(QAbstractSocket::SocketError error);
|
||||
void tryReconnect();
|
||||
|
||||
private:
|
||||
// 发送命令并获取响应(短连接模式)
|
||||
QVariantMap sendCommand(const QString &command, const QString &device_guid, const QString &data = QString());
|
||||
void sendRequst(const QByteArray &data);
|
||||
void processResponse(const QByteArray &response_data);
|
||||
|
||||
private:
|
||||
QMutex _mutex;
|
||||
QString _host;
|
||||
quint16 _port;
|
||||
QThread *_workerThread;
|
||||
QMutex _mutex;
|
||||
QTcpSocket *_tcp_socket;
|
||||
QTimer *_reconnect_timer;
|
||||
bool _is_auto_reconnect;
|
||||
QByteArray *_response_buffer;
|
||||
qint32 _response_data_len;
|
||||
};
|
||||
|
||||
#endif // MEASURECLIENT_H
|
||||
|
|
@ -2,9 +2,8 @@ INCLUDEPATH += $${PWD}
|
|||
DEPENDPATH += $${PWD}
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/MeasureClient.cpp \
|
||||
$$PWD/MeasureWorker.cpp
|
||||
$$PWD/MeasureClient.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/MeasureClient.h \
|
||||
$$PWD/MeasureWorker.h
|
||||
$$PWD/MeasureServiceProtocol.h
|
||||
34
src/MeasureClient/MeasureServiceProtocol.h
Normal file
34
src/MeasureClient/MeasureServiceProtocol.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef MEASURESERVICEPROTOCOL_H
|
||||
#define MEASURESERVICEPROTOCOL_H
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
namespace Protocol {
|
||||
// 固定协议头长度:8字节
|
||||
const int HEAD_SIZE = 8;
|
||||
|
||||
// 打包数据:添加长度头
|
||||
inline QByteArray PackData(const QByteArray &data) {
|
||||
QByteArray buffer;
|
||||
buffer.resize(HEAD_SIZE);
|
||||
// 前4字节 = 数据总长度
|
||||
qint32 data_len = data.size();
|
||||
memcpy(buffer.data(), &data_len, 4);
|
||||
// 后4字节保留
|
||||
qint32 reserve = 0xFFFFFFFF;
|
||||
memcpy(buffer.data() + 4, &reserve, 4);
|
||||
buffer.append(data);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// 解包:从头部获取数据长度
|
||||
inline qint32 UnpackDataLen(const QByteArray &head) {
|
||||
if (head.size() < HEAD_SIZE)
|
||||
return 0;
|
||||
qint32 len = 0;
|
||||
memcpy(&len, head.constData(), 4);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MEASURESERVICEPROTOCOL_H
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
#include "MeasureWorker.h"
|
||||
#include "MeasureClient.h"
|
||||
#include <QDir>
|
||||
#include "GlobalDefine.h"
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
|
||||
MeasureWorker* MeasureWorker::_s_instance { nullptr };
|
||||
|
||||
MeasureWorker::MeasureWorker(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
_measure_client = new MeasureClient;
|
||||
connect(_measure_client, &MeasureClient::getDeviceListResult, this, &MeasureWorker::onGetDeviceListResult);
|
||||
connect(_measure_client, &MeasureClient::startMeasureResult, this, &MeasureWorker::onStartMeasureResult);
|
||||
connect(_measure_client, &MeasureClient::stopMeasureResult, this, &MeasureWorker::onStopMeasureResult);
|
||||
connect(_measure_client, &MeasureClient::setMeasureConfigParamsResult, this, &MeasureWorker::onSetMeasureConfigParamsResult);
|
||||
connect(_measure_client, &MeasureClient::clearDataResult, this, &MeasureWorker::onClearDataResult);
|
||||
connect(_measure_client, &MeasureClient::errorOccurred, this, &MeasureWorker::onErrorOccurred);
|
||||
}
|
||||
|
||||
MeasureWorker *MeasureWorker::Instance()
|
||||
{
|
||||
if (!_s_instance) {
|
||||
_s_instance = new MeasureWorker();
|
||||
}
|
||||
return _s_instance;
|
||||
}
|
||||
|
||||
MeasureWorker::~MeasureWorker()
|
||||
{
|
||||
delete _measure_client;
|
||||
}
|
||||
|
||||
void MeasureWorker::SetMeasureProjectName(const QString &project_name)
|
||||
{
|
||||
_measure_project_name = project_name;
|
||||
}
|
||||
|
||||
void MeasureWorker::Connect()
|
||||
{
|
||||
LOG_INFO(QStringLiteral(u"查找测量设备... ..."));
|
||||
_measure_client->getDeviceList();
|
||||
}
|
||||
|
||||
void MeasureWorker::Start()
|
||||
{
|
||||
auto project_model = ProjectList::Instance()->GetProjectModel(_measure_project_name);
|
||||
if (!project_model) {
|
||||
return;
|
||||
}
|
||||
const QString& device_guid = project_model->GetDeviceGuid();
|
||||
if (device_guid.isEmpty()) {
|
||||
LOG_WARN(QStringLiteral(u"未选择测量设备GUID."));
|
||||
return;
|
||||
}
|
||||
const QString& config_filename = project_model->GetMeasureDeviceParamsCfgFilename();
|
||||
QFile json_file(config_filename);
|
||||
if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LOG_WARN(QStringLiteral(u"加载设备参数配置失败:%1").arg(config_filename));
|
||||
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_WARN(QStringLiteral(u"测量设备通道配置参数为空."));
|
||||
return;
|
||||
}
|
||||
LOG_INFO(QStringLiteral(u"开始测量... ..."));
|
||||
_measure_client->startMeasure(device_guid, device_config_info);
|
||||
}
|
||||
|
||||
void MeasureWorker::Stop()
|
||||
{
|
||||
auto project_model = ProjectList::Instance()->GetProjectModel(_measure_project_name);
|
||||
if (!project_model) {
|
||||
return;
|
||||
}
|
||||
const QString& device_guid = project_model->GetDeviceGuid();
|
||||
if (device_guid.isEmpty()) {
|
||||
LOG_WARN(QStringLiteral(u"未选择测量设备GUID."));
|
||||
return;
|
||||
}
|
||||
LOG_INFO(QStringLiteral(u"停止测量... ..."));
|
||||
_measure_client->stopMeasure(device_guid);
|
||||
}
|
||||
|
||||
void MeasureWorker::ClearData()
|
||||
{
|
||||
auto project_model = ProjectList::Instance()->GetProjectModel(_measure_project_name);
|
||||
if (!project_model) {
|
||||
return;
|
||||
}
|
||||
const QString& device_guid = project_model->GetDeviceGuid();
|
||||
if (device_guid.isEmpty()) {
|
||||
LOG_WARN(QStringLiteral(u"未选择测量设备GUID."));
|
||||
return;
|
||||
}
|
||||
LOG_INFO(QStringLiteral(u"清除测量数据... ..."));
|
||||
_measure_client->clearData(device_guid);
|
||||
}
|
||||
|
||||
void MeasureWorker::onStartMeasureResult(bool success, const QString &info)
|
||||
{
|
||||
if (success) {
|
||||
LOG_INFO(QStringLiteral(u"启动测量成功"));
|
||||
LOG_INFO(QStringLiteral(u"测量数据GVF文件: %1").arg(info));
|
||||
} else {
|
||||
LOG_WARN(QStringLiteral(u"启动测量失败: %1").arg(info));
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureWorker::onStopMeasureResult(bool success, const QString &message)
|
||||
{
|
||||
if (success) {
|
||||
LOG_INFO(QStringLiteral(u"停止测量成功"));
|
||||
} else {
|
||||
LOG_WARN(QStringLiteral(u"停止测量失败: %1").arg(message));
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureWorker::onSetMeasureConfigParamsResult(bool success, const QString &message)
|
||||
{
|
||||
if (success) {
|
||||
LOG_INFO(QStringLiteral(u"设置测量参数成功"));
|
||||
} else {
|
||||
LOG_WARN(QStringLiteral(u"设置测量参数失败: %1").arg(message));
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureWorker::onClearDataResult(bool success, const QString &message)
|
||||
{
|
||||
if (success) {
|
||||
LOG_INFO(QStringLiteral(u"清除测量数据成功"));
|
||||
} else {
|
||||
LOG_WARN(QStringLiteral(u"清除测量数据失败: %1").arg(message));
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureWorker::onGetDeviceListResult(bool success, const QStringList &devices)
|
||||
{
|
||||
if (success && !devices.isEmpty()) {
|
||||
LOG_INFO(QStringLiteral(u"获取测量设备GUID成功:%1").arg(devices.first()));
|
||||
auto project_model = ProjectList::Instance()->GetProjectModel(_measure_project_name);
|
||||
if (project_model) {
|
||||
project_model->SetDeviceGuid(devices.first());
|
||||
}
|
||||
} else {
|
||||
LOG_WARN(QStringLiteral(u"获取测量设备失败"));
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureWorker::onErrorOccurred(const QString &errorString)
|
||||
{
|
||||
LOG_WARN(QStringLiteral(u"错误: %1").arg(errorString));
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef MEASUREWORKER_H
|
||||
#define MEASUREWORKER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class MeasureClient;
|
||||
|
||||
class MeasureWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
private:
|
||||
MeasureWorker(QObject* parent = nullptr);
|
||||
static MeasureWorker* _s_instance;
|
||||
|
||||
public:
|
||||
static MeasureWorker* Instance();
|
||||
virtual ~MeasureWorker();
|
||||
|
||||
void SetMeasureProjectName(const QString& project_name);
|
||||
|
||||
void Connect();
|
||||
void Start();
|
||||
void Stop();
|
||||
void ClearData();
|
||||
|
||||
private slots:
|
||||
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 QStringList &devices);
|
||||
void onErrorOccurred(const QString &errorString);
|
||||
|
||||
private:
|
||||
MeasureClient* _measure_client = nullptr;
|
||||
QString _measure_project_name;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -48,7 +48,6 @@ ParticleCountPlotView::ParticleCountPlotView(QWidget* parent)
|
|||
ParticleCountPlotView::~ParticleCountPlotView()
|
||||
{
|
||||
LOG_DEBUG(QStringLiteral(u"%1析构.").arg(this->GetViewName()));
|
||||
|
||||
}
|
||||
|
||||
void ParticleCountPlotView::InitViewWorkspace(const QString& project_name)
|
||||
|
|
@ -178,8 +177,11 @@ void ParticleCountPlotView::setupPlot()
|
|||
_plot->insertLegend(legend, QwtPlot::RightLegend);
|
||||
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
_plot->SetAxisDragScale(QwtPlot::yLeft, true);
|
||||
|
||||
// new CustomQwtPlotXaxisPanner(_plot->canvas());
|
||||
// new CustomQwtPlotXaxisMagnifier(_plot->canvas());
|
||||
|
||||
_data_selector = new CustomQwtPlotXaxisSelector(_plot->canvas());
|
||||
_data_selector->setEnabled(false);
|
||||
}
|
||||
|
|
@ -222,11 +224,16 @@ void ParticleCountPlotView::loadDataFromFile(const QString& data_name, const QSt
|
|||
int address;
|
||||
unsigned long long particle_count;
|
||||
QVector<double> x, y;
|
||||
|
||||
while (reader.read_row(address, particle_count)) {
|
||||
x.push_back(address);
|
||||
y.push_back(particle_count);
|
||||
if ( _x_max < address )
|
||||
_x_max = address;
|
||||
if ( _y_max < particle_count )
|
||||
_y_max = particle_count;
|
||||
}
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, _x_max);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, _y_max);
|
||||
|
||||
// 绘制曲线
|
||||
QwtPlotCurve* curve = new QwtPlotCurve(data_name);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ private:
|
|||
FindPeaksResultDialog* _find_peaks_result_dlg = nullptr;
|
||||
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
|
||||
BatchEnergyScaleDialog* _batch_energy_scale_dlg = nullptr;
|
||||
double _x_max = 0.0f;
|
||||
double _y_max = 0.0f;
|
||||
};
|
||||
|
||||
#endif // PARTICLECOUNTPLOTVIEW_H
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ ParticleInjectTimeAnalysisView::ParticleInjectTimeAnalysisView(QWidget *parent)
|
|||
_plot->enableAxis(QwtPlot::yLeft);
|
||||
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
_plot->SetAxisDragScale(QwtPlot::yLeft, true);
|
||||
|
||||
// // 设置QWT图例
|
||||
// QwtLegend* legend = new QwtLegend();
|
||||
|
|
@ -123,6 +124,7 @@ void ParticleInjectTimeAnalysisView::updateData(bool b_init_update)
|
|||
int board, channel;
|
||||
double energy;
|
||||
unsigned long long time_count;
|
||||
double x_max = 0.0f, y_max = 0.0f;
|
||||
while (in.read_row(board, channel, energy, time_count)) {
|
||||
if ( !b_init_update && (energy <= _begin_enery || energy >= _end_energy)) {
|
||||
continue;
|
||||
|
|
@ -130,7 +132,13 @@ void ParticleInjectTimeAnalysisView::updateData(bool b_init_update)
|
|||
particle_num++;
|
||||
x.append(particle_num);
|
||||
y.append(time_count);
|
||||
if ( x_max < particle_num )
|
||||
x_max = particle_num;
|
||||
if ( y_max < time_count )
|
||||
y_max = time_count;
|
||||
}
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max);
|
||||
_curve->setSamples(x, y);
|
||||
_plot->replot();
|
||||
LOG_INFO(QStringLiteral(u"%1数据更新完毕.").arg(this->GetViewName()));
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ void ParticleTimeDifferenceView::loadDataFromFile()
|
|||
y_max = count;
|
||||
}
|
||||
_histogram->setData(new QwtIntervalSeriesData(samples));
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, _x_max);
|
||||
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, x_max);
|
||||
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, y_max);
|
||||
_plot->replot();
|
||||
const QString& info = QStringLiteral(u"粒子时间差分析处理完成.");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user