添加测量设备参数管理交互实现
This commit is contained in:
parent
79b68ba1d6
commit
664b115aaa
BIN
bin/theme.rcc
BIN
bin/theme.rcc
Binary file not shown.
|
|
@ -6,7 +6,7 @@ LIBS += -L$$PWD/armadillo/lib -llibblas
|
|||
LIBS += -L$$PWD/armadillo/lib -lliblapack
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/CoincidenceSpectrum.cpp \
|
||||
$$PWD/CoincidenceSpectrumProcess.cpp \
|
||||
$$PWD/EnergyEfficiencyFit.cpp \
|
||||
$$PWD/Poly2FindPeaks.cpp \
|
||||
$$PWD/FindPeaksBySvd.cpp \
|
||||
|
|
|
|||
|
|
@ -1,463 +0,0 @@
|
|||
#include "DeviceConfigView.h"
|
||||
#include "DeviceParameterProxy.h"
|
||||
#include <QTableView>
|
||||
#include <QStandardItemModel>
|
||||
#include <QHeaderView>
|
||||
#include <QPushButton>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QMessageBox>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QListWidget>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QScrollArea>
|
||||
#include <QCheckBox>
|
||||
#include <QFileDialog>
|
||||
#include <QStyleOptionButton>
|
||||
#include <GlobalDefine.h>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
class DeviceConfigViewModel: public QStandardItemModel
|
||||
{
|
||||
public:
|
||||
DeviceConfigViewModel(QObject *parent = nullptr) : QStandardItemModel(parent){}
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const {
|
||||
Qt::ItemFlags f = QStandardItemModel::flags(index);
|
||||
if ( index.column() == 0 ) {
|
||||
f = f & Qt::ItemIsUserCheckable;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
DeviceConfigView::DeviceConfigView(QWidget *parent)
|
||||
: MeasureAnalysisView(parent)
|
||||
, m_tableView(nullptr)
|
||||
, m_model(nullptr)
|
||||
{
|
||||
initTableView();
|
||||
}
|
||||
|
||||
DeviceConfigView::~DeviceConfigView()
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceConfigView::initTableView()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_tableView = new QTableView(this);
|
||||
layout->addWidget(m_tableView);
|
||||
|
||||
// 设置表头
|
||||
QStringList headList;
|
||||
headList << tr("数据传输模式") << tr("硬件增益") << tr("硬件增益选择索引")
|
||||
<< tr("软件增益") << tr("时间常数") << tr("成形时间") << tr("快通道触发阈值")
|
||||
<< tr("多道分辨率") << tr("控制功能") << tr("幅度提前延迟") << tr("积分长度")
|
||||
<< tr("dcfd缩放倍数") << tr("dcfd延迟") << tr("直流偏移") << tr("最大能量范围")
|
||||
<< tr("Am 峰面积寻峰法的面积比例") << tr("K40与 Am241的峰位校正系数") << tr("高压关断阈值")
|
||||
<< tr("获取能谱周期") << tr("总测量时间") << tr("总测量次数") << tr("滤波参数")
|
||||
<< tr("上升时间") << tr("平顶时间") << tr("ICR 校正使能") << tr("CRZA 值")
|
||||
<< tr("ZA 使能值") << tr("操作");
|
||||
|
||||
m_model = new DeviceConfigViewModel(this);
|
||||
m_model->setColumnCount(headList.size());
|
||||
m_model->setHorizontalHeaderLabels(headList);
|
||||
m_model->setRowCount(32);
|
||||
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
QString rowName = tr("通道%1").arg(i + 1);
|
||||
m_model->setHeaderData(i, Qt::Vertical, rowName, Qt::DisplayRole);
|
||||
}
|
||||
|
||||
// 操作列最后一列不可编辑
|
||||
int actionCol = headList.size() - 1;
|
||||
for (int row = 0; row < 32; ++row) {
|
||||
QStandardItem *item = new QStandardItem(QString());
|
||||
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
|
||||
m_model->setItem(row, actionCol, item);
|
||||
}
|
||||
|
||||
m_tableView->setModel(m_model);
|
||||
m_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
||||
m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
||||
m_tableView->setEditTriggers(QAbstractItemView::DoubleClicked);
|
||||
// 设置代理
|
||||
DeviceParameterProxy *proxy = new DeviceParameterProxy(this);
|
||||
m_tableView->setItemDelegate(proxy);
|
||||
|
||||
setupActionColumnButtons();
|
||||
}
|
||||
|
||||
void DeviceConfigView::setupActionColumnButtons()
|
||||
{
|
||||
int actionCol = m_model->columnCount() - 1;
|
||||
for (int row = 0; row < m_model->rowCount(); ++row) {
|
||||
QModelIndex idx_0 = m_model->index(row, 0);
|
||||
|
||||
QModelIndex idx = m_model->index(row, actionCol);
|
||||
QPushButton *btn = new QPushButton(tr("应用"), m_tableView);
|
||||
btn->setProperty("row", row);
|
||||
connect(btn, &QPushButton::clicked, this, &DeviceConfigView::onActionButtonClicked);
|
||||
m_tableView->setIndexWidget(idx, btn);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceConfigView::onActionButtonClicked()
|
||||
{
|
||||
QPushButton *btn = qobject_cast<QPushButton*>(sender());
|
||||
if (!btn) return;
|
||||
|
||||
int srcRow = btn->property("row").toInt();
|
||||
int srcChannel = srcRow + 1;
|
||||
|
||||
QList<int> targetChannels = selectTargetChannels(srcChannel);
|
||||
if (targetChannels.isEmpty()) return;
|
||||
|
||||
int paramColCount = m_model->columnCount() - 1;
|
||||
m_model->blockSignals(true);
|
||||
for (int ch : targetChannels) {
|
||||
int dstRow = ch - 1;
|
||||
if (dstRow == srcRow) continue;
|
||||
for (int col = 0; col < paramColCount; ++col) {
|
||||
QVariant srcData = m_model->data(m_model->index(srcRow, col));
|
||||
m_model->setData(m_model->index(dstRow, col), srcData);
|
||||
}
|
||||
}
|
||||
m_model->blockSignals(false);
|
||||
|
||||
emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, paramColCount - 1));
|
||||
QMessageBox::information(this, tr("提示"),
|
||||
tr("已成功将通道%1的参数应用到 %2 个通道").arg(srcChannel).arg(targetChannels.size()));
|
||||
}
|
||||
|
||||
QList<int> DeviceConfigView::selectTargetChannels(int currentChannel) const
|
||||
{
|
||||
QDialog dlg(const_cast<DeviceConfigView*>(this));
|
||||
dlg.setWindowTitle(tr("选择目标通道"));
|
||||
dlg.resize(300, 400);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(&dlg);
|
||||
QLabel *label = new QLabel(tr("请选择要应用参数的目标通道(可多选):"));
|
||||
layout->addWidget(label);
|
||||
|
||||
QListWidget *listWidget = new QListWidget(&dlg);
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
QString itemText = tr("通道 %1").arg(i);
|
||||
if (i == currentChannel) itemText += tr(" (源通道)");
|
||||
QListWidgetItem *item = new QListWidgetItem(itemText, listWidget);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
item->setData(Qt::UserRole, i);
|
||||
if (i == currentChannel) {
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
|
||||
}
|
||||
}
|
||||
layout->addWidget(listWidget);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg);
|
||||
layout->addWidget(buttonBox);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
|
||||
|
||||
QList<int> selected;
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
for (int i = 0; i < listWidget->count(); ++i) {
|
||||
QListWidgetItem *item = listWidget->item(i);
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
int ch = item->data(Qt::UserRole).toInt();
|
||||
if (ch != currentChannel) selected.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
bool DeviceConfigView::loadJson(const QString &filePath)
|
||||
{
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qWarning() << "无法打开文件:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
QByteArray jsonData = file.readAll();
|
||||
file.close();
|
||||
return parseJsonImpl(jsonData);
|
||||
}
|
||||
|
||||
bool DeviceConfigView::parseJsonImpl(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "JSON 解析错误:" << parseError.errorString();
|
||||
return false;
|
||||
}
|
||||
if (!jsonDoc.isObject()) {
|
||||
qWarning() << "JSON 文档不是对象";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject rootObj = jsonDoc.object();
|
||||
QJsonArray channelsArray = rootObj["channels"].toArray();
|
||||
|
||||
m_model->blockSignals(true);
|
||||
|
||||
// 清空现有数据
|
||||
for (int row = 0; row < m_model->rowCount(); ++row) {
|
||||
for (int col = 0; col < m_model->columnCount(); ++col) {
|
||||
m_model->setData(m_model->index(row, col), QVariant());
|
||||
}
|
||||
}
|
||||
|
||||
int count = qMin(channelsArray.size(), m_model->rowCount());
|
||||
for (int i = 0; i < count; ++i) {
|
||||
QJsonValue channelValue = channelsArray[i];
|
||||
if (!channelValue.isObject()) continue;
|
||||
QJsonObject channelObj = channelValue.toObject();
|
||||
|
||||
for (int col = 0; col < m_model->columnCount(); ++col) {
|
||||
QString header = m_model->headerData(col, Qt::Horizontal).toString();
|
||||
QString jsonKey = m_columnToJsonKey.value(header);
|
||||
if (jsonKey.isEmpty()) continue;
|
||||
|
||||
QJsonValue value = channelObj[jsonKey];
|
||||
if (value.isUndefined()) continue;
|
||||
|
||||
if (value.isString())
|
||||
m_model->setData(m_model->index(i, col), value.toString());
|
||||
else if (value.isDouble())
|
||||
m_model->setData(m_model->index(i, col), value.toDouble());
|
||||
else if (value.isBool())
|
||||
m_model->setData(m_model->index(i, col), value.toBool());
|
||||
}
|
||||
}
|
||||
|
||||
emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, m_model->columnCount() - 1));
|
||||
emit dataChanged();
|
||||
|
||||
m_tableView->viewport()->update();
|
||||
m_tableView->horizontalHeader()->update();
|
||||
m_tableView->verticalHeader()->update();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceConfigView::saveJson(const QString &filePath)
|
||||
{
|
||||
QJsonObject rootObj;
|
||||
rootObj["command"] = "SET";
|
||||
QJsonArray channelsArray;
|
||||
|
||||
for (int row = 0; row < m_model->rowCount(); ++row) {
|
||||
QJsonObject channelObj;
|
||||
for (int col = 0; col < m_model->columnCount(); ++col) {
|
||||
QString header = m_model->headerData(col, Qt::Horizontal).toString();
|
||||
QString jsonKey = m_columnToJsonKey.value(header);
|
||||
if (jsonKey.isEmpty()) continue;
|
||||
|
||||
QVariant value = m_model->index(row, col).data(Qt::EditRole);
|
||||
if (!value.isValid() || value.isNull()) continue;
|
||||
channelObj[jsonKey] = QJsonValue::fromVariant(value);
|
||||
}
|
||||
channelsArray.append(channelObj);
|
||||
}
|
||||
|
||||
rootObj["channels"] = channelsArray;
|
||||
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qWarning() << "无法创建文件:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
QJsonDocument doc(rootObj);
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
QStandardItemModel* DeviceConfigView::getModel() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void DeviceConfigView::showColumnControlDialog()
|
||||
{
|
||||
int colCount = m_model->columnCount();
|
||||
if (colCount == 0) return;
|
||||
|
||||
QDialog dlg(this);
|
||||
dlg.setWindowTitle(tr("列显示控制"));
|
||||
dlg.resize(800, 400);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(&dlg);
|
||||
|
||||
// 工具栏
|
||||
QHBoxLayout *row1Layout = new QHBoxLayout();
|
||||
QPushButton *btnSelectAll = new QPushButton(tr("全选"));
|
||||
QPushButton *btnInvert = new QPushButton(tr("反选"));
|
||||
QPushButton *btnSave = new QPushButton(tr("保存配置"));
|
||||
QPushButton *btnLoad = new QPushButton(tr("加载配置"));
|
||||
row1Layout->addWidget(btnSelectAll);
|
||||
row1Layout->addWidget(btnInvert);
|
||||
row1Layout->addWidget(btnSave);
|
||||
row1Layout->addWidget(btnLoad);
|
||||
row1Layout->addStretch();
|
||||
mainLayout->addLayout(row1Layout);
|
||||
|
||||
QScrollArea *scrollArea = new QScrollArea();
|
||||
scrollArea->setWidgetResizable(true);
|
||||
QWidget *scrollWidget = new QWidget();
|
||||
QGridLayout *gridLayout = new QGridLayout(scrollWidget);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
mainLayout->addWidget(scrollArea);
|
||||
|
||||
int gridCols = std::sqrt(colCount);
|
||||
if (gridCols < 1) gridCols = 1;
|
||||
|
||||
QMap<int, QCheckBox*> colCheckBoxMap;
|
||||
for (int col = 0; col < colCount; ++col) {
|
||||
QString header = m_model->headerData(col, Qt::Horizontal).toString();
|
||||
QCheckBox *cb = new QCheckBox(header);
|
||||
cb->setChecked(!m_tableView->isColumnHidden(col));
|
||||
connect(cb, &QCheckBox::toggled, this, [this, col](bool checked) {
|
||||
m_tableView->setColumnHidden(col, !checked);
|
||||
});
|
||||
int row = col / gridCols;
|
||||
int colInGrid = col % gridCols;
|
||||
gridLayout->addWidget(cb, row, colInGrid);
|
||||
colCheckBoxMap[col] = cb;
|
||||
}
|
||||
|
||||
connect(btnSelectAll, &QPushButton::clicked, this, [colCheckBoxMap, this]() {
|
||||
// 先断开所有复选框的信号
|
||||
for (QCheckBox *cb : colCheckBoxMap) {
|
||||
cb->blockSignals(true);
|
||||
cb->setChecked(true);
|
||||
cb->blockSignals(false);
|
||||
}
|
||||
// 一次性更新所有列的隐藏状态
|
||||
for (int col : colCheckBoxMap.keys()) {
|
||||
m_tableView->setColumnHidden(col, !colCheckBoxMap[col]->isChecked());
|
||||
}
|
||||
});
|
||||
connect(btnInvert, &QPushButton::clicked, this, [colCheckBoxMap, this]() {
|
||||
for (QCheckBox *cb : colCheckBoxMap) {
|
||||
cb->blockSignals(true);
|
||||
cb->setChecked(!cb->isChecked());
|
||||
cb->blockSignals(false);
|
||||
}
|
||||
for (int col : colCheckBoxMap.keys()) {
|
||||
m_tableView->setColumnHidden(col, !colCheckBoxMap[col]->isChecked());
|
||||
}
|
||||
});
|
||||
connect(btnSave, &QPushButton::clicked, this, [this, &dlg, colCheckBoxMap]() {
|
||||
QString saveDir = QDir::currentPath() + "/columnConfigs";
|
||||
QDir().mkpath(saveDir);
|
||||
QString fileName = QFileDialog::getSaveFileName(&dlg, tr("保存列配置"),
|
||||
saveDir + "/untitled.json",
|
||||
"JSON Files (*.json)");
|
||||
if (fileName.isEmpty()) return;
|
||||
|
||||
QJsonObject root;
|
||||
for (int col = 0; col < m_model->columnCount(); ++col) {
|
||||
QString header = m_model->headerData(col, Qt::Horizontal).toString();
|
||||
bool checked = colCheckBoxMap[col]->isChecked();
|
||||
root[header] = checked;
|
||||
}
|
||||
|
||||
QJsonDocument doc(root);
|
||||
QFile file(fileName);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
QMessageBox::information(&dlg, tr("成功"), tr("列配置已保存"));
|
||||
} else {
|
||||
QMessageBox::warning(&dlg, tr("错误"), tr("无法保存文件:%1").arg(file.errorString()));
|
||||
}
|
||||
});
|
||||
|
||||
connect(btnLoad, &QPushButton::clicked, this, [this, &dlg, colCheckBoxMap]() {
|
||||
QString loadDir = QDir::currentPath() + "/columnConfigs";
|
||||
QString fileName = QFileDialog::getOpenFileName(&dlg, tr("加载列配置"),
|
||||
loadDir, "JSON Files (*.json)");
|
||||
if (fileName.isEmpty()) return;
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
QMessageBox::warning(&dlg, tr("错误"), tr("无法打开文件:%1").arg(file.errorString()));
|
||||
return;
|
||||
}
|
||||
QByteArray data = file.readAll();
|
||||
file.close();
|
||||
|
||||
QJsonParseError err;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data, &err);
|
||||
if (err.error != QJsonParseError::NoError || !doc.isObject()) {
|
||||
QMessageBox::warning(&dlg, tr("错误"), tr("JSON解析失败"));
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject root = doc.object();
|
||||
for (int col = 0; col < m_model->columnCount(); ++col) {
|
||||
QString header = m_model->headerData(col, Qt::Horizontal).toString();
|
||||
if (root.contains(header)) {
|
||||
colCheckBoxMap[col]->blockSignals(true);
|
||||
colCheckBoxMap[col]->setChecked(root[header].toBool(false));
|
||||
colCheckBoxMap[col]->blockSignals(false);
|
||||
}
|
||||
}
|
||||
// 一次性更新列隐藏
|
||||
for (int col : colCheckBoxMap.keys()) {
|
||||
m_tableView->setColumnHidden(col, !colCheckBoxMap[col]->isChecked());
|
||||
}
|
||||
});
|
||||
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void DeviceConfigView::reset()
|
||||
{
|
||||
m_model->blockSignals(true);
|
||||
for (int row = 0; row < m_model->rowCount(); ++row) {
|
||||
for (int col = 0; col < m_model->columnCount(); ++col) {
|
||||
m_model->setData(m_model->index(row, col), QVariant());
|
||||
}
|
||||
}
|
||||
m_model->blockSignals(false);
|
||||
emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, m_model->columnCount() - 1));
|
||||
}
|
||||
|
||||
void DeviceConfigView::setColumnMapping(const QHash<QString, QString> &mapping)
|
||||
{
|
||||
m_columnToJsonKey = mapping;
|
||||
// 构建反向映射(可选)
|
||||
m_jsonKeyToColumn.clear();
|
||||
for (auto it = m_columnToJsonKey.constBegin(); it != m_columnToJsonKey.constEnd(); ++it) {
|
||||
m_jsonKeyToColumn[it.value()] = m_model->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString().indexOf(it.key());
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceConfigView::InitViewWorkspace(const QString &project_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DeviceConfigView::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||
{
|
||||
if (data_files_set.isEmpty()) {
|
||||
LOG_WARN("文件集合为空");
|
||||
return;
|
||||
}
|
||||
|
||||
QString filePath = data_files_set.first().toString();
|
||||
LOG_INFO("读取文件: " + filePath);
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#ifndef DEVICECONFIGVIEW_H
|
||||
#define DEVICECONFIGVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QHash>
|
||||
#include "MeasureAnalysisView.h"
|
||||
|
||||
class QTableView;
|
||||
class QStandardItemModel;
|
||||
class QPushButton;
|
||||
|
||||
|
||||
class DeviceConfigView : public MeasureAnalysisView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceConfigView(QWidget *parent = nullptr);
|
||||
~DeviceConfigView();
|
||||
|
||||
|
||||
bool loadJson(const QString &filePath);
|
||||
|
||||
|
||||
bool saveJson(const QString &filePath);
|
||||
|
||||
|
||||
QStandardItemModel* getModel() const;
|
||||
|
||||
|
||||
void showColumnControlDialog();
|
||||
|
||||
|
||||
void reset();
|
||||
|
||||
|
||||
void setColumnMapping(const QHash<QString, QString> &mapping);
|
||||
|
||||
virtual void InitViewWorkspace(const QString& project_name) override final;
|
||||
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set);
|
||||
|
||||
QList<int> getCheckedRows() const;
|
||||
|
||||
signals:
|
||||
|
||||
void dataChanged();
|
||||
|
||||
private slots:
|
||||
void onActionButtonClicked();
|
||||
|
||||
private:
|
||||
void initTableView();
|
||||
void setupActionColumnButtons();
|
||||
bool parseJsonImpl(const QByteArray &data);
|
||||
QList<int> selectTargetChannels(int currentChannel) const;
|
||||
|
||||
QTableView *m_tableView;
|
||||
QStandardItemModel *m_model;
|
||||
QHash<QString, QString> m_columnToJsonKey; // 列头 -> JSON键名
|
||||
QHash<QString, int> m_jsonKeyToColumn; // 反向映射,用于快速查找列索引
|
||||
};
|
||||
|
||||
#endif // DEVICECONFIGVIEW_H
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
#include "DeviceParameterConfig.h"
|
||||
#include "DeviceParameterConfigList.h"
|
||||
#include "DeviceConfigView.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QTextEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
|
||||
DeviceParameterConfig::DeviceParameterConfig(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_configList(nullptr)
|
||||
, m_configView(nullptr)
|
||||
, m_lineEditFileName(nullptr)
|
||||
, m_textEditRemark(nullptr)
|
||||
, m_checkBoxSaveToDevice(nullptr)
|
||||
, m_btnSave(nullptr)
|
||||
, m_btnSetColumn(nullptr)
|
||||
{
|
||||
setupUi();
|
||||
initColumnMapping(); // 设置默认映射
|
||||
m_configView->setColumnMapping(m_columnToJsonKey);
|
||||
m_configList->loadConfigsFromFolder(); // 加载默认目录下的配置文件
|
||||
}
|
||||
|
||||
DeviceParameterConfig::~DeviceParameterConfig()
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::setupUi()
|
||||
{
|
||||
// 主布局:左右分栏
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(10);
|
||||
|
||||
// 左侧:配置列表
|
||||
m_configList = new DeviceParameterConfigList(this);
|
||||
mainLayout->addWidget(m_configList, 1);
|
||||
|
||||
// 右侧:垂直布局
|
||||
QVBoxLayout *rightLayout = new QVBoxLayout();
|
||||
mainLayout->addLayout(rightLayout, 9);
|
||||
|
||||
// 右侧上部:文件名、保存按钮、备注说明
|
||||
QHBoxLayout *topLayout = new QHBoxLayout();
|
||||
QLabel *labelName = new QLabel(QStringLiteral(u"配置命名:"), this);
|
||||
m_lineEditFileName = new QLineEdit(this);
|
||||
m_btnSave = new QPushButton(QStringLiteral(u"保存到测量分析"), this);
|
||||
m_checkBoxSaveToDevice = new QCheckBox(QStringLiteral(u"保存到设备参数配置管理"), this);
|
||||
topLayout->addWidget(labelName);
|
||||
topLayout->addWidget(m_lineEditFileName, 1);
|
||||
topLayout->addWidget(m_btnSave);
|
||||
topLayout->addWidget(m_checkBoxSaveToDevice);
|
||||
rightLayout->addLayout(topLayout);
|
||||
|
||||
QHBoxLayout *remarkLayout = new QHBoxLayout();
|
||||
QLabel *labelRemark = new QLabel(QStringLiteral(u"备注说明:"), this);
|
||||
m_textEditRemark = new QTextEdit(this);
|
||||
m_textEditRemark->setMaximumHeight(80);
|
||||
remarkLayout->addWidget(labelRemark);
|
||||
remarkLayout->addWidget(m_textEditRemark, 1);
|
||||
rightLayout->addLayout(remarkLayout);
|
||||
|
||||
// 右侧中部:设置列按钮
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout();
|
||||
m_btnSetColumn = new QPushButton(QStringLiteral(u"设置列"), this);
|
||||
buttonLayout->addWidget(m_btnSetColumn);
|
||||
buttonLayout->addStretch();
|
||||
rightLayout->addLayout(buttonLayout);
|
||||
|
||||
// 右侧下部:参数表格视图
|
||||
m_configView = new DeviceConfigView(this);
|
||||
rightLayout->addWidget(m_configView, 1);
|
||||
|
||||
// 连接信号槽
|
||||
connect(m_configList, &DeviceParameterConfigList::configSelected,
|
||||
this, &DeviceParameterConfig::onConfigSelected);
|
||||
connect(m_configList, &DeviceParameterConfigList::configDeleted,
|
||||
this, &DeviceParameterConfig::onConfigDeleted);
|
||||
connect(m_btnSave, &QPushButton::clicked,
|
||||
this, &DeviceParameterConfig::onSaveButtonClicked);
|
||||
connect(m_btnSetColumn, &QPushButton::clicked,
|
||||
this, &DeviceParameterConfig::onSetColumnButtonClicked);
|
||||
connect(m_configList, &DeviceParameterConfigList::createNewConfigRequested,
|
||||
this, &DeviceParameterConfig::onCreateNewConfigRequested);
|
||||
connect(m_configView, &DeviceConfigView::dataChanged,
|
||||
this, [this]() {
|
||||
// 数据改变时,在文件名后添加星号表示未保存
|
||||
if (!m_lineEditFileName->text().isEmpty() && !m_lineEditFileName->text().endsWith(" *")) {
|
||||
m_lineEditFileName->setText(m_lineEditFileName->text() + " *");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::initColumnMapping()
|
||||
{
|
||||
// 与原 EquipmentParameterSettingManagement 完全相同的映射
|
||||
m_columnToJsonKey.clear();
|
||||
m_columnToJsonKey[QStringLiteral(u"数据传输模式")] = "eTransferModel";
|
||||
m_columnToJsonKey[QStringLiteral(u"硬件增益")] = "iDeviceGain";
|
||||
m_columnToJsonKey[QStringLiteral(u"硬件增益选择索引")] = "iDeviceGainSelectIndex";
|
||||
m_columnToJsonKey[QStringLiteral(u"软件增益")] = "iSoftGain";
|
||||
m_columnToJsonKey[QStringLiteral(u"时间常数")] = "dConstTime";
|
||||
m_columnToJsonKey[QStringLiteral(u"成形时间")] = "iFormTime";
|
||||
m_columnToJsonKey[QStringLiteral(u"快通道触发阈值")] = "iFastChannelTrigerValue";
|
||||
m_columnToJsonKey[QStringLiteral(u"多道分辨率")] = "iChannelNum";
|
||||
m_columnToJsonKey[QStringLiteral(u"控制功能")] = "";
|
||||
m_columnToJsonKey[QStringLiteral(u"幅度提前延迟")] = "";
|
||||
m_columnToJsonKey[QStringLiteral(u"积分长度")] = "";
|
||||
m_columnToJsonKey[QStringLiteral(u"dcfd缩放倍数")] = "";
|
||||
m_columnToJsonKey[QStringLiteral(u"dcfd延迟")] = "";
|
||||
m_columnToJsonKey[QStringLiteral(u"直流偏移")] = "iCurrentOffset";
|
||||
m_columnToJsonKey[QStringLiteral(u"最大能量范围")] = "iMaxEnergy";
|
||||
m_columnToJsonKey[QStringLiteral(u"Am 峰面积寻峰法的面积比例")] = "iAMPeakDiv";
|
||||
m_columnToJsonKey[QStringLiteral(u"K40与 Am241的峰位校正系数")] = "iHVDelt";
|
||||
m_columnToJsonKey[QStringLiteral(u"高压关断阈值")] = "iHVDelt";
|
||||
m_columnToJsonKey[QStringLiteral(u"获取能谱周期")] = "iGetSpecturmPeirod";
|
||||
m_columnToJsonKey[QStringLiteral(u"总测量时间")] = "iTotalMeasureTime";
|
||||
m_columnToJsonKey[QStringLiteral(u"总测量次数")] = "iTotalMeasureCount";
|
||||
m_columnToJsonKey[QStringLiteral(u"滤波参数")] = "iTrapeTopShitBit";
|
||||
m_columnToJsonKey[QStringLiteral(u"上升时间")] = "iRiseTime";
|
||||
m_columnToJsonKey[QStringLiteral(u"平顶时间")] = "iTopTime";
|
||||
m_columnToJsonKey[QStringLiteral(u"ICR 校正使能")] = "bICRCorrect";
|
||||
m_columnToJsonKey[QStringLiteral(u"CRZA 值")] = "iCRZAValue";
|
||||
m_columnToJsonKey[QStringLiteral(u"ZA 使能值")] = "iZAEnable";
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::setColumnMapping(const QHash<QString, QString> &mapping)
|
||||
{
|
||||
m_columnToJsonKey = mapping;
|
||||
m_configView->setColumnMapping(mapping);
|
||||
}
|
||||
|
||||
bool DeviceParameterConfig::loadConfig(const QString &filePath)
|
||||
{
|
||||
if (!m_configView->loadJson(filePath))
|
||||
return false;
|
||||
|
||||
m_currentFilePath = filePath;
|
||||
QFileInfo info(filePath);
|
||||
m_lineEditFileName->setText(info.fileName());
|
||||
|
||||
// 读取 JSON 中的备注字段
|
||||
QFile file(filePath);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QByteArray data = file.readAll();
|
||||
file.close();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
if (doc.isObject()) {
|
||||
QJsonObject obj = doc.object();
|
||||
if (obj.contains("remark")) {
|
||||
m_textEditRemark->setPlainText(obj["remark"].toString());
|
||||
} else {
|
||||
m_textEditRemark->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit configLoaded(filePath); // 此信号未在头文件中声明,可添加;若不需要可移除
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceParameterConfig::saveCurrentConfig()
|
||||
{
|
||||
if (m_currentFilePath.isEmpty()) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"没有选中的配置文件"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// 保存表格数据
|
||||
if (!m_configView->saveJson(m_currentFilePath))
|
||||
return false;
|
||||
|
||||
// 保存备注到 JSON
|
||||
QFile file(m_currentFilePath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "无法打开文件读取备注:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
QByteArray data = file.readAll();
|
||||
file.close();
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
if (!doc.isObject()) {
|
||||
qWarning() << "JSON 不是对象";
|
||||
return false;
|
||||
}
|
||||
QJsonObject root = doc.object();
|
||||
root["remark"] = m_textEditRemark->toPlainText();
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qWarning() << "无法写入文件:" << file.errorString();
|
||||
return false;
|
||||
}
|
||||
file.write(QJsonDocument(root).toJson());
|
||||
file.close();
|
||||
|
||||
// 移除文件名后的星号
|
||||
QString fileName = m_lineEditFileName->text();
|
||||
if (fileName.endsWith(" *"))
|
||||
fileName.chop(2);
|
||||
m_lineEditFileName->setText(fileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString DeviceParameterConfig::getCurrentFileName() const
|
||||
{
|
||||
return QFileInfo(m_currentFilePath).fileName();
|
||||
}
|
||||
|
||||
QString DeviceParameterConfig::getRemark() const
|
||||
{
|
||||
return m_textEditRemark->toPlainText();
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::setRemark(const QString &remark)
|
||||
{
|
||||
m_textEditRemark->setPlainText(remark);
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::onConfigSelected(const QString &filePath)
|
||||
{
|
||||
loadConfig(filePath);
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::onConfigDeleted(const QString &fileName)
|
||||
{
|
||||
if (m_lineEditFileName->text() == fileName) {
|
||||
m_lineEditFileName->clear();
|
||||
m_textEditRemark->clear();
|
||||
m_configView->reset();
|
||||
m_currentFilePath.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::onCreateNewConfigRequested(const QString &fileName)
|
||||
{
|
||||
QString filePath = QDir::currentPath() + "/parameterConfig/" + fileName;
|
||||
if (createDefaultConfigFile(filePath)) {
|
||||
// 刷新列表
|
||||
m_configList->refresh();
|
||||
// 选中新建的文件
|
||||
m_configList->setCurrentFile(fileName);
|
||||
// 自动加载该配置(可选)
|
||||
loadConfig(filePath);
|
||||
} else {
|
||||
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"无法创建配置文件:%1").arg(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::onSaveButtonClicked()
|
||||
{
|
||||
if (!saveCurrentConfig()) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"保存配置文件失败"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果勾选了“保存到设备参数配置管理”,刷新左侧列表
|
||||
if (m_checkBoxSaveToDevice->isChecked()) {
|
||||
m_configList->refresh();
|
||||
}
|
||||
|
||||
// 发出信号,供外部处理(例如将参数发送到测量分析模块)
|
||||
emit saveToMeasurementRequested(m_currentFilePath);
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::onSetColumnButtonClicked()
|
||||
{
|
||||
m_configView->showColumnControlDialog();
|
||||
}
|
||||
|
||||
bool DeviceParameterConfig::createDefaultConfigFile(const QString &filePath)
|
||||
{
|
||||
// 创建默认配置文件(含 32 个通道)
|
||||
QJsonObject rootObj;
|
||||
rootObj["command"] = "SET";
|
||||
QJsonArray channelsArray;
|
||||
|
||||
QJsonObject defaultChannel;
|
||||
defaultChannel["eTransferModel"] = "eSpecturmMode";
|
||||
defaultChannel["iDeviceGain"] = 1;
|
||||
defaultChannel["iDeviceGainSelectIndex"] = 1;
|
||||
defaultChannel["iSoftGain"] = 3000;
|
||||
defaultChannel["dConstTime"] = 45.0;
|
||||
defaultChannel["iFormTime"] = 3;
|
||||
defaultChannel["iFastChannelTrigerValue"] = 10.0;
|
||||
defaultChannel["iChannelNum"] = 1024;
|
||||
defaultChannel["iHighVoltage"] = 0;
|
||||
defaultChannel["iInputVoltageDesc"] = 0;
|
||||
defaultChannel["iCRDivMode"] = 0;
|
||||
defaultChannel["iInputSignalPostive"] = 0;
|
||||
defaultChannel["iCurrentOffset"] = 0;
|
||||
defaultChannel["iMaxEnergy"] = 0;
|
||||
defaultChannel["iAMPeakDiv"] = 0;
|
||||
defaultChannel["iHVDelt"] = 0;
|
||||
defaultChannel["iHVCtrl"] = 0;
|
||||
defaultChannel["iGetSpecturmPeirod"] = 1;
|
||||
defaultChannel["iTotalMeasureTime"] = 10;
|
||||
defaultChannel["iTotalMeasureCount"] = 1;
|
||||
defaultChannel["iTrapeTopShitBit"] = 0;
|
||||
defaultChannel["iRiseTime"] = 2;
|
||||
defaultChannel["iTopTime"] = 2;
|
||||
defaultChannel["bICRCorrect"] = false;
|
||||
defaultChannel["iCRZAValue"] = 0;
|
||||
defaultChannel["iZAEnable"] = 30;
|
||||
defaultChannel["reserve"] = QJsonArray();
|
||||
defaultChannel["pUserConfigInfo"] = QJsonObject();
|
||||
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
channelsArray.append(defaultChannel);
|
||||
}
|
||||
rootObj["channels"] = channelsArray;
|
||||
rootObj["remark"] = "";
|
||||
|
||||
QJsonDocument doc(rootObj);
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly))
|
||||
return false;
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
#ifndef DEVICEPARAMETERCONFIG_H
|
||||
#define DEVICEPARAMETERCONFIG_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QHash>
|
||||
|
||||
class DeviceParameterConfigList;
|
||||
class DeviceConfigView;
|
||||
class QLineEdit;
|
||||
class QTextEdit;
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
|
||||
|
||||
class DeviceParameterConfig : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceParameterConfig(QWidget *parent = nullptr);
|
||||
~DeviceParameterConfig();
|
||||
|
||||
|
||||
void setColumnMapping(const QHash<QString, QString> &mapping);
|
||||
|
||||
|
||||
bool loadConfig(const QString &filePath);
|
||||
|
||||
|
||||
bool saveCurrentConfig();
|
||||
|
||||
|
||||
QString getCurrentFileName() const;
|
||||
|
||||
|
||||
QString getRemark() const;
|
||||
|
||||
|
||||
void setRemark(const QString &remark);
|
||||
|
||||
signals:
|
||||
|
||||
void saveToMeasurementRequested(const QString &filePath);
|
||||
|
||||
void configLoaded(QString );
|
||||
|
||||
private slots:
|
||||
void onConfigSelected(const QString &filePath);
|
||||
void onConfigDeleted(const QString &fileName);
|
||||
void onCreateNewConfigRequested(const QString &fileName);
|
||||
void onSaveButtonClicked();
|
||||
void onSetColumnButtonClicked();
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
bool createDefaultConfigFile(const QString &filePath);
|
||||
void initColumnMapping(); // 初始化默认映射(若外部未调用则使用默认)
|
||||
|
||||
// 子控件
|
||||
DeviceParameterConfigList *m_configList;
|
||||
DeviceConfigView *m_configView;
|
||||
|
||||
// 周边控件
|
||||
QLineEdit *m_lineEditFileName;
|
||||
QTextEdit *m_textEditRemark;
|
||||
QCheckBox *m_checkBoxSaveToDevice;
|
||||
QPushButton *m_btnSave;
|
||||
QPushButton *m_btnSetColumn;
|
||||
|
||||
QString m_currentFilePath;
|
||||
QHash<QString, QString> m_columnToJsonKey; // 列头->JSON键映射
|
||||
};
|
||||
|
||||
#endif // DEVICEPARAMETERCONFIG_H
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
#include "DeviceParameterConfigList.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <QLabel>
|
||||
DeviceParameterConfigList::DeviceParameterConfigList(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_listWidget(nullptr)
|
||||
, m_btnAdd(nullptr)
|
||||
, m_btnDelete(nullptr)
|
||||
{
|
||||
setupUi();
|
||||
}
|
||||
|
||||
DeviceParameterConfigList::~DeviceParameterConfigList()
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::setupUi()
|
||||
{
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QLabel *ListWidgetName = new QLabel(QStringLiteral(u"设备参数配置列表"));
|
||||
mainLayout->addWidget(ListWidgetName);
|
||||
|
||||
m_listWidget = new QListWidget(this);
|
||||
mainLayout->addWidget(m_listWidget);
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout();
|
||||
m_btnAdd = new QPushButton(QStringLiteral(u"添加"), this);
|
||||
m_btnDelete = new QPushButton(QStringLiteral(u"删除"), this);
|
||||
btnLayout->addWidget(m_btnAdd);
|
||||
btnLayout->addWidget(m_btnDelete);
|
||||
btnLayout->addStretch();
|
||||
mainLayout->addLayout(btnLayout);
|
||||
|
||||
connect(m_listWidget, &QListWidget::itemClicked, this, &DeviceParameterConfigList::onItemClicked);
|
||||
connect(m_btnAdd, &QPushButton::clicked, this, &DeviceParameterConfigList::onAddClicked);
|
||||
connect(m_btnDelete, &QPushButton::clicked, this, &DeviceParameterConfigList::onDeleteClicked);
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::loadConfigsFromFolder(const QString &folderPath)
|
||||
{
|
||||
if (folderPath.isEmpty()) {
|
||||
m_folderPath = QDir::currentPath() + "/parameterConfig";
|
||||
} else {
|
||||
m_folderPath = folderPath;
|
||||
}
|
||||
|
||||
QDir dir(m_folderPath);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(m_folderPath);
|
||||
}
|
||||
|
||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||
QStringList files = dir.entryList();
|
||||
updateList(files);
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::updateList(const QStringList &fileList)
|
||||
{
|
||||
m_listWidget->clear();
|
||||
for (const QString &file : fileList) {
|
||||
if (file.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
m_listWidget->addItem(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString DeviceParameterConfigList::getCurrentFilePath() const
|
||||
{
|
||||
QListWidgetItem *item = m_listWidget->currentItem();
|
||||
if (!item) return QString();
|
||||
return m_folderPath + "/" + item->text();
|
||||
}
|
||||
|
||||
QString DeviceParameterConfigList::getCurrentFileName() const
|
||||
{
|
||||
QListWidgetItem *item = m_listWidget->currentItem();
|
||||
return item ? item->text() : QString();
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::setCurrentFile(const QString &fileName)
|
||||
{
|
||||
QList<QListWidgetItem*> items = m_listWidget->findItems(fileName, Qt::MatchExactly);
|
||||
if (!items.isEmpty()) {
|
||||
m_listWidget->setCurrentItem(items.first());
|
||||
emit configSelected(getCurrentFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::refresh()
|
||||
{
|
||||
loadConfigsFromFolder(m_folderPath);
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::onItemClicked(QListWidgetItem *item)
|
||||
{
|
||||
if (item) {
|
||||
emit configSelected(m_folderPath + "/" + item->text());
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::onAddClicked()
|
||||
{
|
||||
bool ok;
|
||||
QString fileName = QInputDialog::getText(this, QStringLiteral(u"新建配置"),
|
||||
QStringLiteral(u"请输入配置文件名(无需后缀):"),
|
||||
QLineEdit::Normal,
|
||||
QString("NewConfig_%1").arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")),
|
||||
&ok);
|
||||
if (!ok || fileName.isEmpty()) return;
|
||||
|
||||
if (!fileName.endsWith(".json", Qt::CaseInsensitive))
|
||||
fileName += ".json";
|
||||
|
||||
QString filePath = m_folderPath + "/" + fileName;
|
||||
if (QFile::exists(filePath)) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"文件已存在,请使用其他名称。"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 发出创建请求,由外部(主窗口)决定默认内容
|
||||
emit createNewConfigRequested(fileName);
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::onDeleteClicked()
|
||||
{
|
||||
QListWidgetItem *currentItem = m_listWidget->currentItem();
|
||||
if (!currentItem) {
|
||||
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请先选择要删除的配置文件。"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString fileName = currentItem->text();
|
||||
QString filePath = m_folderPath + "/" + fileName;
|
||||
|
||||
int ret = QMessageBox::question(this, QStringLiteral(u"确认删除"),
|
||||
QStringLiteral(u"确定要删除文件 \"%1\" 吗?").arg(fileName),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret != QMessageBox::Yes) return;
|
||||
|
||||
QFile file(filePath);
|
||||
if (file.remove()) {
|
||||
delete currentItem;
|
||||
emit configDeleted(fileName);
|
||||
QMessageBox::information(this, QStringLiteral(u"成功"), QStringLiteral(u"文件已删除。"));
|
||||
} else {
|
||||
QMessageBox::warning(this, QStringLiteral(u"错误"), QStringLiteral(u"无法删除文件:%1").arg(file.errorString()));
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceParameterConfigList::createDefaultConfigFile(const QString &filePath)
|
||||
{
|
||||
// 默认配置内容(与原来保持一致)
|
||||
QJsonObject rootObj;
|
||||
rootObj["command"] = "SET";
|
||||
QJsonArray channelsArray;
|
||||
|
||||
QJsonObject defaultChannel;
|
||||
defaultChannel["eTransferModel"] = "eSpecturmMode";
|
||||
defaultChannel["iDeviceGain"] = 1;
|
||||
defaultChannel["iDeviceGainSelectIndex"] = 1;
|
||||
defaultChannel["iSoftGain"] = 3000;
|
||||
defaultChannel["dConstTime"] = 45.0;
|
||||
defaultChannel["iFormTime"] = 3;
|
||||
defaultChannel["iFastChannelTrigerValue"] = 10.0;
|
||||
defaultChannel["iChannelNum"] = 1024;
|
||||
defaultChannel["iHighVoltage"] = 0;
|
||||
defaultChannel["iInputVoltageDesc"] = 0;
|
||||
defaultChannel["iCRDivMode"] = 0;
|
||||
defaultChannel["iInputSignalPostive"] = 0;
|
||||
defaultChannel["iCurrentOffset"] = 0;
|
||||
defaultChannel["iMaxEnergy"] = 0;
|
||||
defaultChannel["iAMPeakDiv"] = 0;
|
||||
defaultChannel["iHVDelt"] = 0;
|
||||
defaultChannel["iHVCtrl"] = 0;
|
||||
defaultChannel["iGetSpecturmPeirod"] = 1;
|
||||
defaultChannel["iTotalMeasureTime"] = 10;
|
||||
defaultChannel["iTotalMeasureCount"] = 1;
|
||||
defaultChannel["iTrapeTopShitBit"] = 0;
|
||||
defaultChannel["iRiseTime"] = 2;
|
||||
defaultChannel["iTopTime"] = 2;
|
||||
defaultChannel["bICRCorrect"] = false;
|
||||
defaultChannel["iCRZAValue"] = 0;
|
||||
defaultChannel["iZAEnable"] = 30;
|
||||
defaultChannel["reserve"] = QJsonArray();
|
||||
defaultChannel["pUserConfigInfo"] = QJsonObject();
|
||||
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
channelsArray.append(defaultChannel);
|
||||
}
|
||||
rootObj["channels"] = channelsArray;
|
||||
|
||||
QJsonDocument doc(rootObj);
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#ifndef DEVICEPARAMETERCONFIGLIST_H
|
||||
#define DEVICEPARAMETERCONFIGLIST_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
|
||||
|
||||
class DeviceParameterConfigList : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceParameterConfigList(QWidget *parent = nullptr);
|
||||
~DeviceParameterConfigList();
|
||||
|
||||
|
||||
void loadConfigsFromFolder(const QString &folderPath = QString());
|
||||
|
||||
|
||||
QString getCurrentFilePath() const;
|
||||
|
||||
|
||||
QString getCurrentFileName() const;
|
||||
|
||||
|
||||
void setCurrentFile(const QString &fileName);
|
||||
|
||||
void refresh();
|
||||
|
||||
signals:
|
||||
|
||||
void configSelected(const QString &filePath);
|
||||
|
||||
void configDeleted(const QString &fileName);
|
||||
|
||||
void createNewConfigRequested(const QString &fileName);
|
||||
|
||||
private slots:
|
||||
void onItemClicked(QListWidgetItem *item);
|
||||
void onAddClicked();
|
||||
void onDeleteClicked();
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
void updateList(const QStringList &fileList);
|
||||
bool createDefaultConfigFile(const QString &filePath);
|
||||
|
||||
QListWidget *m_listWidget;
|
||||
QPushButton *m_btnAdd;
|
||||
QPushButton *m_btnDelete;
|
||||
QString m_folderPath;
|
||||
};
|
||||
|
||||
#endif // DEVICEPARAMETERCONFIGLIST_H
|
||||
|
|
@ -1,384 +0,0 @@
|
|||
#include "DeviceParameterProxy.h"
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSpinBox>
|
||||
#include <QLineEdit>
|
||||
#include <QToolTip>
|
||||
#include <QTimer>
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpressionValidator>
|
||||
#include <QDebug>
|
||||
|
||||
DeviceParameterProxy::DeviceParameterProxy(QObject *parent) : QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QWidget* DeviceParameterProxy::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
int col = index.column();
|
||||
switch (col)
|
||||
{
|
||||
case 0: // 数据传输模式(枚举)
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << QStringLiteral(u"谱线模式") << QStringLiteral(u"波形模式") << QStringLiteral(u"ADC模式") << QStringLiteral(u"列表模式") << QStringLiteral(u"α/β模式"));
|
||||
return combo;
|
||||
}
|
||||
case 1: // 硬件增益(档位)
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << QStringLiteral(u"1") << QStringLiteral(u"2") << QStringLiteral(u"4") << QStringLiteral(u"8") << QStringLiteral(u"16"));
|
||||
return combo;
|
||||
}
|
||||
case 2: // 硬件增益选择索引
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << QStringLiteral(u"1") << QStringLiteral(u"2") << QStringLiteral(u"3") << QStringLiteral(u"4") << QStringLiteral(u"5"));
|
||||
return combo;
|
||||
}
|
||||
case 3: // 软件增益(32位无符号)
|
||||
{
|
||||
QLineEdit *edit = new QLineEdit(parent);
|
||||
edit->setValidator(new UInt32Validator(edit));
|
||||
edit->setProperty("rangeHint", "0 ~ 4294967295");
|
||||
edit->installEventFilter(const_cast<DeviceParameterProxy*>(this));
|
||||
return edit;
|
||||
}
|
||||
case 4: // 时间常数(double μs)
|
||||
{
|
||||
QDoubleSpinBox *spin = new QDoubleSpinBox(parent);
|
||||
spin->setRange(0.0, 1000.0);
|
||||
spin->setSingleStep(1.0);
|
||||
spin->setDecimals(2);
|
||||
return spin;
|
||||
}
|
||||
case 5: // 成形时间(int μs)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(1, 10);
|
||||
return spin;
|
||||
}
|
||||
case 6: // 快通道触发阈值(double 0.1mV)
|
||||
{
|
||||
QDoubleSpinBox *spin = new QDoubleSpinBox(parent);
|
||||
spin->setRange(0.0, 10000.0);
|
||||
spin->setSingleStep(0.1);
|
||||
spin->setDecimals(1);
|
||||
return spin;
|
||||
}
|
||||
case 7: // 多道分辨率(2的幂)
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << QStringLiteral(u"256") << QStringLiteral(u"512") << QStringLiteral(u"1024") << QStringLiteral(u"2048") << QStringLiteral(u"4096") << QStringLiteral(u"8192") << QStringLiteral(u"16384"));
|
||||
return combo;
|
||||
}
|
||||
case 8: // 控制功能(位掩码,暂用十进制输入)
|
||||
{
|
||||
QLineEdit *edit = new QLineEdit(parent);
|
||||
// 允许输入十进制数字,不设范围限制(业务层处理)
|
||||
return edit;
|
||||
}
|
||||
case 9: // 幅度提前延迟(unsigned char)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 255);
|
||||
return spin;
|
||||
}
|
||||
case 10: // 积分长度(unsigned char)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 255);
|
||||
return spin;
|
||||
}
|
||||
case 11: // dcfd缩放倍数(unsigned char)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 255);
|
||||
return spin;
|
||||
}
|
||||
case 12: // dcfd延迟(unsigned char)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 255);
|
||||
return spin;
|
||||
}
|
||||
case 13: // 直流偏移(mV)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(-1000, 1000);
|
||||
return spin;
|
||||
}
|
||||
case 14: // 最大能量范围(keV)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 99999);
|
||||
return spin;
|
||||
}
|
||||
case 15: // Am峰面积寻峰法的面积比例(%)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 100);
|
||||
return spin;
|
||||
}
|
||||
case 16: // K40与Am241的峰位校正系数(short)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(-32768, 32767);
|
||||
return spin;
|
||||
}
|
||||
case 17: // 高压关断阈值(short)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(-32768, 32767);
|
||||
return spin;
|
||||
}
|
||||
case 18: // 获取能谱周期(秒)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 86400); // 一天
|
||||
return spin;
|
||||
}
|
||||
case 19: // 总测量时间(__int64,64位)
|
||||
{
|
||||
QLineEdit *edit = new QLineEdit(parent);
|
||||
edit->setValidator(new Int64Validator(edit));
|
||||
edit->setProperty("rangeHint", "0 ~ 9223372036854775807");
|
||||
edit->installEventFilter(const_cast<DeviceParameterProxy*>(this));
|
||||
return edit;
|
||||
}
|
||||
case 20: // 总测量次数
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 1000000); // 可调大
|
||||
return spin;
|
||||
}
|
||||
case 21: // 滤波参数
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 3);
|
||||
return spin;
|
||||
}
|
||||
case 22: // 上升时间(μs)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(1, 255);
|
||||
return spin;
|
||||
}
|
||||
case 23: // 平顶时间(μs)
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(1, 255);
|
||||
return spin;
|
||||
}
|
||||
case 24: // ICR校正使能(布尔)
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << QStringLiteral(u"关闭") << QStringLiteral(u"启用"));
|
||||
return combo;
|
||||
}
|
||||
case 25: // CRZA值
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 1000000); // 合理范围
|
||||
return spin;
|
||||
}
|
||||
case 26: // ZA使能值
|
||||
{
|
||||
QSpinBox *spin = new QSpinBox(parent);
|
||||
spin->setRange(0, 100);
|
||||
return spin;
|
||||
}
|
||||
default:
|
||||
return new QLineEdit(parent);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterProxy::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
{
|
||||
QVariant value = index.data(Qt::EditRole);
|
||||
int col = index.column();
|
||||
|
||||
switch (col)
|
||||
{
|
||||
case 0: // QComboBox
|
||||
case 1:
|
||||
case 2:
|
||||
case 7:
|
||||
case 24:
|
||||
{
|
||||
QComboBox *combo = qobject_cast<QComboBox*>(editor);
|
||||
if (combo) {
|
||||
int idx = combo->findText(value.toString());
|
||||
if (idx >= 0) combo->setCurrentIndex(idx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: // QLineEdit(软件增益)
|
||||
case 8: // QLineEdit(控制功能)
|
||||
case 19: // QLineEdit(总测量时间)
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
if (edit) edit->setText(value.toString());
|
||||
break;
|
||||
}
|
||||
case 4: // QDoubleSpinBox
|
||||
case 6:
|
||||
{
|
||||
QDoubleSpinBox *spin = qobject_cast<QDoubleSpinBox*>(editor);
|
||||
if (spin) spin->setValue(value.toDouble());
|
||||
break;
|
||||
}
|
||||
case 5: // QSpinBox
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 25:
|
||||
case 26:
|
||||
{
|
||||
QSpinBox *spin = qobject_cast<QSpinBox*>(editor);
|
||||
if (spin) spin->setValue(value.toInt());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
if (edit) edit->setText(value.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterProxy::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
int col = index.column();
|
||||
|
||||
switch (col)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 7:
|
||||
case 24:
|
||||
{
|
||||
QComboBox *combo = qobject_cast<QComboBox*>(editor);
|
||||
if (combo) model->setData(index, combo->currentText());
|
||||
break;
|
||||
}
|
||||
case 3: // 软件增益(字符串存储,因为可能超出int范围)
|
||||
case 8: // 控制功能(字符串存储)
|
||||
case 19: // 总测量时间(字符串存储)
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
// if (edit) model->setData(index, edit->text());
|
||||
if (edit) {
|
||||
// 提交前再次验证(防止通过回车提交无效数据)
|
||||
QString text = edit->text();
|
||||
int pos = 0;
|
||||
if (edit->validator() && edit->validator()->validate(text, pos) == QValidator::Acceptable) {
|
||||
model->setData(index, text);
|
||||
} else {
|
||||
// 无效数据不写入模型,并显示提示
|
||||
QString rangeHint = edit->property("rangeHint").toString();
|
||||
QPoint pos = edit->mapToGlobal(edit->rect().topRight());
|
||||
QToolTip::showText(pos, QString("取值范围: %1").arg(rangeHint), edit);
|
||||
// 焦点留在编辑器(但此时编辑器即将销毁,所以需要延迟重新打开?)
|
||||
// 实际上 setModelData 被调用时编辑器即将销毁,我们无法阻止。
|
||||
// 因此更好的方法是在事件过滤器中拦截回车,避免走到这里。
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
case 6:
|
||||
{
|
||||
QDoubleSpinBox *spin = qobject_cast<QDoubleSpinBox*>(editor);
|
||||
if (spin) model->setData(index, spin->value());
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 25:
|
||||
case 26:
|
||||
{
|
||||
QSpinBox *spin = qobject_cast<QSpinBox*>(editor);
|
||||
if (spin) model->setData(index, spin->value());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
if (edit) model->setData(index, edit->text());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterProxy::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
editor->setGeometry(option.rect);
|
||||
}
|
||||
|
||||
bool DeviceParameterProxy::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(obj);
|
||||
if (!edit || !edit->validator())
|
||||
return QStyledItemDelegate::eventFilter(obj, event);
|
||||
|
||||
if (event->type() == QEvent::FocusOut) {
|
||||
QString text = edit->text();
|
||||
int pos = 0;
|
||||
if (edit->validator()->validate(text, pos) != QValidator::Acceptable) {
|
||||
QString rangeHint = edit->property("rangeHint").toString();
|
||||
QPoint pos = edit->mapToGlobal(edit->rect().topRight());
|
||||
QToolTip::showText(pos, QStringLiteral(u"取值范围: %1").arg(rangeHint), edit);
|
||||
// 延迟重新获得焦点
|
||||
QTimer::singleShot(0, edit, SLOT(setFocus()));
|
||||
return true; // 阻止焦点离开
|
||||
} else {
|
||||
QToolTip::hideText();
|
||||
}
|
||||
}
|
||||
else if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
|
||||
QString text = edit->text();
|
||||
int pos = 0;
|
||||
if (edit->validator()->validate(text, pos) != QValidator::Acceptable) {
|
||||
QString rangeHint = edit->property("rangeHint").toString();
|
||||
QPoint pos = edit->mapToGlobal(edit->rect().topRight());
|
||||
QToolTip::showText(pos, QStringLiteral(u"取值范围: %1").arg(rangeHint), edit);
|
||||
return true; // 拦截回车,不提交
|
||||
} else {
|
||||
QToolTip::hideText();
|
||||
// 允许回车提交,Qt 会正常处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::eventFilter(obj, event);
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
#ifndef DEVICEPARAMETERPROXY_H
|
||||
#define DEVICEPARAMETERPROXY_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QIntValidator>
|
||||
#include <QLineEdit>
|
||||
|
||||
// ==================== 自定义验证器 ====================
|
||||
|
||||
/**
|
||||
* @brief 无符号32位整数验证器(范围 0 ~ 4294967295)
|
||||
*/
|
||||
class UInt32Validator : public QValidator
|
||||
{
|
||||
public:
|
||||
UInt32Validator(QObject *parent = nullptr) : QValidator(parent) {}
|
||||
|
||||
State validate(QString &input, int &pos) const override
|
||||
{
|
||||
if (input.isEmpty())
|
||||
return Intermediate;
|
||||
|
||||
bool ok;
|
||||
quint64 value = input.toULongLong(&ok);
|
||||
if (!ok)
|
||||
return Invalid;
|
||||
|
||||
if (value <= 4294967295ULL)
|
||||
return Acceptable;
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
void fixup(QString &input) const override
|
||||
{
|
||||
input.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 有符号64位整数验证器(范围 0 ~ 9223372036854775807)
|
||||
* 用于总测量时间(__int64)
|
||||
*/
|
||||
class Int64Validator : public QValidator
|
||||
{
|
||||
public:
|
||||
Int64Validator(QObject *parent = nullptr) : QValidator(parent) {}
|
||||
|
||||
State validate(QString &input, int &pos) const override
|
||||
{
|
||||
if (input.isEmpty())
|
||||
return Intermediate;
|
||||
|
||||
bool ok;
|
||||
qint64 value = input.toLongLong(&ok);
|
||||
if (!ok)
|
||||
return Invalid;
|
||||
|
||||
if (value >= 0 && value <= 9223372036854775807LL)
|
||||
return Acceptable;
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
void fixup(QString &input) const override
|
||||
{
|
||||
input.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 设备参数表格的代理类,用于自定义单元格的编辑器
|
||||
*
|
||||
* 根据不同的列(参数类型)提供不同的编辑控件,例如下拉框、数字输入框等。
|
||||
*/
|
||||
class DeviceParameterProxy : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceParameterProxy(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief 创建编辑器控件,根据列索引返回不同的编辑器
|
||||
* @param parent 父窗口
|
||||
* @param option 样式选项
|
||||
* @param index 当前单元格的索引
|
||||
* @return 返回对应列的编辑器控件指针
|
||||
*/
|
||||
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
/**
|
||||
* @brief 将模型中的数据设置到编辑器中
|
||||
* @param editor 编辑器控件
|
||||
* @param index 当前单元格的索引
|
||||
*/
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||
|
||||
/**
|
||||
* @brief 将编辑器中的数据写回模型
|
||||
* @param editor 编辑器控件
|
||||
* @param model 数据模型
|
||||
* @param index 当前单元格的索引
|
||||
*/
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
||||
|
||||
/**
|
||||
* @brief 更新编辑器的几何位置
|
||||
* @param editor 编辑器控件
|
||||
* @param option 样式选项
|
||||
* @param index 当前单元格的索引
|
||||
*/
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override; // 事件过滤器,用于验证输入和显示提示
|
||||
};
|
||||
|
||||
|
||||
#endif // DEVICEPARAMETERPROXY_H
|
||||
|
|
@ -1,37 +1,35 @@
|
|||
#define NOMINMAX
|
||||
|
||||
//#include <locale>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
// #include <locale>
|
||||
#include "EnergyCountPeakFitView.h"
|
||||
#include "CustomQwtPlot.h"
|
||||
#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>
|
||||
#include <QFileInfo>
|
||||
#include "PlotRectItem.h"
|
||||
#include <QInputDialog>
|
||||
#include <QDebug>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QListWidget>
|
||||
#include <QDateTime>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QDir>
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QListWidget>
|
||||
#include <QMessageBox>
|
||||
|
||||
QJsonObject PeakFitHistoryItem::toJson() const
|
||||
{
|
||||
|
|
@ -67,7 +65,7 @@ PeakFitHistoryItem PeakFitHistoryItem::fromJson(const QJsonObject& obj)
|
|||
return item;
|
||||
}
|
||||
|
||||
EnergyCountPeakFitView::EnergyCountPeakFitView(QWidget *parent)
|
||||
EnergyCountPeakFitView::EnergyCountPeakFitView(QWidget* parent)
|
||||
: MeasureAnalysisView { parent }
|
||||
{
|
||||
this->setViewType(PlotFrame);
|
||||
|
|
@ -84,29 +82,31 @@ EnergyCountPeakFitView::~EnergyCountPeakFitView()
|
|||
{
|
||||
LOG_DEBUG(QStringLiteral(u"%1析构.").arg(this->GetViewName()));
|
||||
delete _rubberBand;
|
||||
clearAllSelectionRects();
|
||||
clearFitCurves();
|
||||
clearAllSelectionRects();
|
||||
clearFitCurves();
|
||||
}
|
||||
|
||||
void EnergyCountPeakFitView::InitViewWorkspace(const QString &project_name)
|
||||
void EnergyCountPeakFitView::InitViewWorkspace(const QString& project_name)
|
||||
{
|
||||
Q_UNUSED(project_name);
|
||||
if (project_name.isEmpty()) return;
|
||||
auto project_model = ProjectList::Instance()->GetProjectModel(project_name);
|
||||
if (!project_model) return;
|
||||
if (project_name.isEmpty())
|
||||
return;
|
||||
auto project_model = ProjectList::Instance()->GetProjectModel(project_name);
|
||||
if (!project_model)
|
||||
return;
|
||||
|
||||
QDir project_dir(project_model->GetProjectDir());
|
||||
_workspace = project_dir.filePath(this->GetViewName());
|
||||
if (!QDir(_workspace).exists())
|
||||
project_dir.mkpath(_workspace);
|
||||
QDir project_dir(project_model->GetProjectDir());
|
||||
_workspace = project_dir.filePath(this->GetViewName());
|
||||
if (!QDir(_workspace).exists())
|
||||
project_dir.mkpath(_workspace);
|
||||
|
||||
_historyFilePath = QDir(_workspace).filePath("peak_fit_history.json");
|
||||
loadHistoryFromFile();
|
||||
_historyFilePath = QDir(_workspace).filePath("peak_fit_history.json");
|
||||
loadHistoryFromFile();
|
||||
}
|
||||
|
||||
void EnergyCountPeakFitView::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||
void EnergyCountPeakFitView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
||||
{
|
||||
if ( !data_files_set.isEmpty() ) {
|
||||
if (!data_files_set.isEmpty()) {
|
||||
const QString& data_name = data_files_set.firstKey();
|
||||
const QString& data_filename = data_files_set.first().toString();
|
||||
if (QFileInfo(data_filename).exists()) {
|
||||
|
|
@ -138,9 +138,9 @@ void EnergyCountPeakFitView::setupPlot()
|
|||
_plot->enableAxis(QwtPlot::yLeft);
|
||||
|
||||
// 设置QWT图例
|
||||
QwtLegend* legend = new QwtLegend();
|
||||
legend->setDefaultItemMode(QwtLegendData::ReadOnly);
|
||||
_plot->insertLegend(legend, QwtPlot::RightLegend);
|
||||
QwtLegend* legend = new QwtLegend();
|
||||
legend->setDefaultItemMode(QwtLegendData::ReadOnly);
|
||||
_plot->insertLegend(legend, QwtPlot::RightLegend);
|
||||
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
|
||||
|
|
@ -150,9 +150,6 @@ void EnergyCountPeakFitView::setupPlot()
|
|||
// 启用鼠标追踪,并安装事件过滤器
|
||||
_plot->canvas()->setMouseTracking(true);
|
||||
_plot->canvas()->installEventFilter(this);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void EnergyCountPeakFitView::setupMenu()
|
||||
|
|
@ -178,25 +175,25 @@ void EnergyCountPeakFitView::setupMenu()
|
|||
QAction* action_clear_rect = this->_menu->addAction(QStringLiteral(u"清除框选标记"));
|
||||
connect(action_clear_rect, &QAction::triggered, this, &EnergyCountPeakFitView::clearAllSelectionRects);
|
||||
|
||||
// this->_menu->addSeparator();
|
||||
// QAction* action_select_algorithm = this->_menu->addAction(QStringLiteral(u"选择拟合算法"));
|
||||
// this->_menu->addSeparator();
|
||||
// QAction* action_select_algorithm = this->_menu->addAction(QStringLiteral(u"选择拟合算法"));
|
||||
|
||||
QAction* action_clear_fit = this->_menu->addAction(QStringLiteral(u"清除拟合曲线"));
|
||||
connect(action_clear_fit, &QAction::triggered, this, &EnergyCountPeakFitView::clearFitCurves);
|
||||
connect(action_clear_fit, &QAction::triggered, this, &EnergyCountPeakFitView::clearFitCurves);
|
||||
|
||||
// [NEW] 保存当前拟合结果
|
||||
QAction* action_save_fit = this->_menu->addAction(QStringLiteral(u"保存当前拟合结果"));
|
||||
connect(action_save_fit, &QAction::triggered, this, &EnergyCountPeakFitView::onActionSaveCurrentFit);
|
||||
// [NEW] 保存当前拟合结果
|
||||
QAction* action_save_fit = this->_menu->addAction(QStringLiteral(u"保存当前拟合结果"));
|
||||
connect(action_save_fit, &QAction::triggered, this, &EnergyCountPeakFitView::onActionSaveCurrentFit);
|
||||
|
||||
// [NEW] 查看历史拟合结果
|
||||
QAction* action_show_history = this->_menu->addAction(QStringLiteral(u"峰拟合结果"));
|
||||
connect(action_show_history, &QAction::triggered, this, &EnergyCountPeakFitView::onActionShowFitHistory);
|
||||
// [NEW] 查看历史拟合结果
|
||||
QAction* action_show_history = this->_menu->addAction(QStringLiteral(u"峰拟合结果"));
|
||||
connect(action_show_history, &QAction::triggered, this, &EnergyCountPeakFitView::onActionShowFitHistory);
|
||||
|
||||
QAction* action_hint = this->_menu->addAction(QStringLiteral(u"框选提示:按住 Ctrl 键并拖动左键"));
|
||||
action_hint->setEnabled(false);
|
||||
}
|
||||
|
||||
void EnergyCountPeakFitView::loadDataFromFile(const QString &data_name, const QString &filename)
|
||||
void EnergyCountPeakFitView::loadDataFromFile(const QString& data_name, const QString& filename)
|
||||
{
|
||||
std::string address_str = QString(QStringLiteral(u"能量(KeV)")).toStdString();
|
||||
std::string count_str = QString(QStringLiteral(u"计数")).toStdString();
|
||||
|
|
@ -220,7 +217,7 @@ void EnergyCountPeakFitView::loadDataFromFile(const QString &data_name, const QS
|
|||
// 绘制曲线
|
||||
QwtPlotCurve* curve = new QwtPlotCurve(QStringLiteral(u"原始数据"));
|
||||
curve->setSamples(x, y);
|
||||
curve->setPen(QPen(Qt::red, 2)); // 原始数据统一红色
|
||||
curve->setPen(QPen(Qt::red, 2)); // 原始数据统一红色
|
||||
_plot->AddCurve(curve);
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +243,7 @@ void EnergyCountPeakFitView::onActionCurveShowSetting()
|
|||
QVBoxLayout* checkbox_layout = new QVBoxLayout();
|
||||
QHBoxLayout* checkbox_column_layout = new QHBoxLayout();
|
||||
QMap<QwtPlotCurve*, QCheckBox*> curve_checkbox_map;
|
||||
auto addCurveToLayout = [&](const QString& curve_name){
|
||||
auto addCurveToLayout = [&](const QString& curve_name) {
|
||||
QwtPlotCurve* curve = this->_plot->GetCurve(curve_name);
|
||||
QCheckBox* check_box = new QCheckBox(curve->title().text());
|
||||
check_box->setChecked(curve->isVisible());
|
||||
|
|
@ -302,50 +299,44 @@ void EnergyCountPeakFitView::onActionCurveShowSetting()
|
|||
|
||||
void EnergyCountPeakFitView::onActionPlotConfigure()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EnergyCountPeakFitView::clearAllSelectionRects()
|
||||
{
|
||||
for (PlotRectItem* item : _selectionRectItems) {
|
||||
if (item) {
|
||||
item->detach();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
_selectionRectItems.clear();
|
||||
_plot->replot();
|
||||
if (item) {
|
||||
item->detach();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
_selectionRectItems.clear();
|
||||
_plot->replot();
|
||||
}
|
||||
|
||||
bool EnergyCountPeakFitView::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
if (watched == _plot->canvas()) {
|
||||
QMouseEvent* me = static_cast<QMouseEvent*>(event);
|
||||
QMouseEvent* me = static_cast<QMouseEvent*>(event);
|
||||
|
||||
// 按下 Ctrl+左键 开始框选
|
||||
if (event->type() == QEvent::MouseButtonPress &&
|
||||
me->button() == Qt::LeftButton &&
|
||||
(me->modifiers() & Qt::ControlModifier)) {
|
||||
startSelection(me->pos());
|
||||
// 按下 Ctrl+左键 开始框选
|
||||
if (event->type() == QEvent::MouseButtonPress && me->button() == Qt::LeftButton && (me->modifiers() & Qt::ControlModifier)) {
|
||||
startSelection(me->pos());
|
||||
|
||||
return true;
|
||||
}
|
||||
// 移动时更新橡皮筋
|
||||
else if (event->type() == QEvent::MouseMove && _isSelecting) {
|
||||
updateSelection(me->pos());
|
||||
return true;
|
||||
}
|
||||
// 释放左键完成框选
|
||||
else if (event->type() == QEvent::MouseButtonRelease &&
|
||||
me->button() == Qt::LeftButton && _isSelecting) {
|
||||
finishSelection();
|
||||
fadeSelectionRectBorders();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return MeasureAnalysisView::eventFilter(watched, event);
|
||||
return true;
|
||||
}
|
||||
// 移动时更新橡皮筋
|
||||
else if (event->type() == QEvent::MouseMove && _isSelecting) {
|
||||
updateSelection(me->pos());
|
||||
return true;
|
||||
}
|
||||
// 释放左键完成框选
|
||||
else if (event->type() == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton && _isSelecting) {
|
||||
finishSelection();
|
||||
fadeSelectionRectBorders();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return MeasureAnalysisView::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void EnergyCountPeakFitView::startSelection(const QPoint& pos)
|
||||
|
|
@ -364,321 +355,319 @@ void EnergyCountPeakFitView::startSelection(const QPoint& pos)
|
|||
|
||||
void EnergyCountPeakFitView::updateSelection(const QPoint& pos)
|
||||
{
|
||||
if (!_rubberBand) return;
|
||||
int canvasHeight = _plot->canvas()->height();
|
||||
int x1 = _selectionStart.x();
|
||||
int x2 = pos.x();
|
||||
int left = qMin(x1, x2);
|
||||
int width = qAbs(x1 - x2);
|
||||
_rubberBand->setGeometry(QRect(left, 0, width, canvasHeight));
|
||||
if (!_rubberBand)
|
||||
return;
|
||||
int canvasHeight = _plot->canvas()->height();
|
||||
int x1 = _selectionStart.x();
|
||||
int x2 = pos.x();
|
||||
int left = qMin(x1, x2);
|
||||
int width = qAbs(x1 - x2);
|
||||
_rubberBand->setGeometry(QRect(left, 0, width, canvasHeight));
|
||||
}
|
||||
void EnergyCountPeakFitView::finishSelection()
|
||||
{
|
||||
if (_rubberBand)
|
||||
{
|
||||
QRect finalRect = _rubberBand->geometry();
|
||||
_rubberBand->hide();
|
||||
if (_rubberBand) {
|
||||
QRect finalRect = _rubberBand->geometry();
|
||||
_rubberBand->hide();
|
||||
|
||||
if (finalRect.width() > 2) {
|
||||
const QwtScaleMap xMap = _plot->canvasMap(QwtPlot::xBottom);
|
||||
double xMin = xMap.invTransform(finalRect.left());
|
||||
double xMax = xMap.invTransform(finalRect.right());
|
||||
if (xMin > xMax) std::swap(xMin, xMax);
|
||||
if (finalRect.width() > 2) {
|
||||
const QwtScaleMap xMap = _plot->canvasMap(QwtPlot::xBottom);
|
||||
double xMin = xMap.invTransform(finalRect.left());
|
||||
double xMax = xMap.invTransform(finalRect.right());
|
||||
if (xMin > xMax)
|
||||
std::swap(xMin, xMax);
|
||||
|
||||
double yMin = _plot->axisScaleDiv(QwtPlot::yLeft).lowerBound();
|
||||
double yMax = _plot->axisScaleDiv(QwtPlot::yLeft).upperBound();
|
||||
QRectF plotRect(xMin, yMin, xMax - xMin, yMax - yMin);
|
||||
addSelectionRect(plotRect);
|
||||
double yMin = _plot->axisScaleDiv(QwtPlot::yLeft).lowerBound();
|
||||
double yMax = _plot->axisScaleDiv(QwtPlot::yLeft).upperBound();
|
||||
QRectF plotRect(xMin, yMin, xMax - xMin, yMax - yMin);
|
||||
addSelectionRect(plotRect);
|
||||
|
||||
// 获取曲线数据
|
||||
QList<QwtPlotCurve*> curves = _plot->GetCurveList();
|
||||
if (!curves.isEmpty()) {
|
||||
QwtPlotCurve* originalCurve = curves.first();
|
||||
QVector<double> origX, origY;
|
||||
for (size_t i = 0; i < originalCurve->dataSize(); ++i) {
|
||||
origX.push_back(originalCurve->sample(i).x());
|
||||
origY.push_back(originalCurve->sample(i).y());
|
||||
// 获取曲线数据
|
||||
QList<QwtPlotCurve*> curves = _plot->GetCurveList();
|
||||
if (!curves.isEmpty()) {
|
||||
QwtPlotCurve* originalCurve = curves.first();
|
||||
QVector<double> origX, origY;
|
||||
for (size_t i = 0; i < originalCurve->dataSize(); ++i) {
|
||||
origX.push_back(originalCurve->sample(i).x());
|
||||
origY.push_back(originalCurve->sample(i).y());
|
||||
}
|
||||
|
||||
QVector<double> roiX, roiY;
|
||||
for (int i = 0; i < origX.size(); ++i) {
|
||||
if (origX[i] >= xMin && origX[i] <= xMax) {
|
||||
roiX.push_back(origX[i]);
|
||||
roiY.push_back(origY[i]);
|
||||
}
|
||||
}
|
||||
|
||||
QVector<double> roiX, roiY;
|
||||
for (int i = 0; i < origX.size(); ++i) {
|
||||
if (origX[i] >= xMin && origX[i] <= xMax) {
|
||||
roiX.push_back(origX[i]);
|
||||
roiY.push_back(origY[i]);
|
||||
if (roiX.size() >= 3) {
|
||||
QStringList algorithms;
|
||||
algorithms << QStringLiteral(u"光子峰拟合算法");
|
||||
bool ok = false;
|
||||
QString selected = QInputDialog::getItem(this,
|
||||
QStringLiteral(u"选择拟合算法"),
|
||||
QStringLiteral(u"请选择用于当前框选区域的峰拟合算法:"),
|
||||
algorithms,
|
||||
0,
|
||||
false,
|
||||
&ok);
|
||||
if (ok && selected == QStringLiteral(u"光子峰拟合算法")) {
|
||||
arma::vec armaRoiX(roiX.size()), armaRoiY(roiY.size());
|
||||
for (int i = 0; i < roiX.size(); ++i) {
|
||||
armaRoiX(i) = roiX[i];
|
||||
armaRoiY(i) = roiY[i];
|
||||
}
|
||||
// 1. 自动估算默认初始参数(基于整个 ROI,或取第一个峰)
|
||||
arma::vec defaultP0;
|
||||
bool defaultValid = false;
|
||||
try {
|
||||
defaultP0 = EstimatePhotonPeakModelInitialParams(armaRoiX, armaRoiY);
|
||||
defaultValid = true;
|
||||
} catch (...) {
|
||||
// 估算失败,使用硬编码默认值
|
||||
}
|
||||
if (!defaultValid) {
|
||||
double midEnergy = (roiX.first() + roiX.last()) / 2.0;
|
||||
defaultP0 = { 100.0, 2.0, 50.0, 2.0, 10.0, midEnergy };
|
||||
}
|
||||
|
||||
// 2. 弹出参数设置对话框
|
||||
FitParams defaultParams;
|
||||
defaultParams.A = defaultP0(0);
|
||||
defaultParams.delt = defaultP0(1);
|
||||
defaultParams.H = defaultP0(2);
|
||||
defaultParams.W = defaultP0(3);
|
||||
defaultParams.C = defaultP0(4);
|
||||
defaultParams.P = defaultP0(5);
|
||||
PeakFitParamsDialog paramDlg(defaultParams, this);
|
||||
if (paramDlg.exec() != QDialog::Accepted)
|
||||
return; // 用户取消
|
||||
|
||||
FitParams userParams = paramDlg.getParams();
|
||||
arma::vec userP0 = { userParams.A, userParams.delt, userParams.H,
|
||||
userParams.W, userParams.C, userParams.P };
|
||||
|
||||
// 3. 执行拟合(曲线自动添加到主图)
|
||||
QList<PeakFitResult> results = performPeakFitting(roiX, roiY, &userP0);
|
||||
if (results.isEmpty()) {
|
||||
qDebug() << QStringLiteral(u"拟合结果:") << QStringLiteral(u"未检测到有效峰或拟合失败。");
|
||||
} else {
|
||||
// QMessageBox::information(this, "拟合结果", QString("成功拟合 %1 个峰,曲线已显示在图区。").arg(results.size()));
|
||||
for (const auto& r : results) {
|
||||
qDebug() << QStringLiteral(u"峰中心= %1 keV, FWHM= %2, 面积= %3")
|
||||
.arg(r.center)
|
||||
.arg(r.fwhm)
|
||||
.arg(r.area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (roiX.size() >= 3) {
|
||||
QStringList algorithms;
|
||||
algorithms << QStringLiteral(u"光子峰拟合算法");
|
||||
bool ok = false;
|
||||
QString selected = QInputDialog::getItem(this,
|
||||
QStringLiteral(u"选择拟合算法"),
|
||||
QStringLiteral(u"请选择用于当前框选区域的峰拟合算法:"),
|
||||
algorithms,
|
||||
0,
|
||||
false,
|
||||
&ok);
|
||||
if (ok && selected == QStringLiteral(u"光子峰拟合算法")) {
|
||||
arma::vec armaRoiX(roiX.size()), armaRoiY(roiY.size());
|
||||
for (int i = 0; i < roiX.size(); ++i) {
|
||||
armaRoiX(i) = roiX[i];
|
||||
armaRoiY(i) = roiY[i];
|
||||
}
|
||||
// 1. 自动估算默认初始参数(基于整个 ROI,或取第一个峰)
|
||||
arma::vec defaultP0;
|
||||
bool defaultValid = false;
|
||||
try {
|
||||
defaultP0 = EstimatePhotonPeakModelInitialParams(armaRoiX, armaRoiY);
|
||||
defaultValid = true;
|
||||
} catch (...) {
|
||||
// 估算失败,使用硬编码默认值
|
||||
}
|
||||
if (!defaultValid) {
|
||||
double midEnergy = (roiX.first() + roiX.last()) / 2.0;
|
||||
defaultP0 = {100.0, 2.0, 50.0, 2.0, 10.0, midEnergy};
|
||||
}
|
||||
|
||||
// 2. 弹出参数设置对话框
|
||||
FitParams defaultParams;
|
||||
defaultParams.A = defaultP0(0);
|
||||
defaultParams.delt = defaultP0(1);
|
||||
defaultParams.H = defaultP0(2);
|
||||
defaultParams.W = defaultP0(3);
|
||||
defaultParams.C = defaultP0(4);
|
||||
defaultParams.P = defaultP0(5);
|
||||
PeakFitParamsDialog paramDlg(defaultParams, this);
|
||||
if (paramDlg.exec() != QDialog::Accepted)
|
||||
return; // 用户取消
|
||||
|
||||
FitParams userParams = paramDlg.getParams();
|
||||
arma::vec userP0 = {userParams.A, userParams.delt, userParams.H,
|
||||
userParams.W, userParams.C, userParams.P};
|
||||
|
||||
// 3. 执行拟合(曲线自动添加到主图)
|
||||
QList<PeakFitResult> results = performPeakFitting(roiX, roiY, &userP0);
|
||||
if (results.isEmpty()) {
|
||||
qDebug()<< QStringLiteral(u"拟合结果:") << QStringLiteral(u"未检测到有效峰或拟合失败。");
|
||||
} else {
|
||||
// QMessageBox::information(this, "拟合结果", QString("成功拟合 %1 个峰,曲线已显示在图区。").arg(results.size()));
|
||||
for (const auto& r : results) {
|
||||
qDebug() << QStringLiteral(u"峰中心= %1 keV, FWHM= %2, 面积= %3")
|
||||
.arg(r.center).arg(r.fwhm).arg(r.area);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qDebug() << QStringLiteral(u"框选区域内数据点不足3个,无法拟合。");
|
||||
}
|
||||
} else {
|
||||
qDebug() << QStringLiteral(u"框选区域内数据点不足3个,无法拟合。");
|
||||
}
|
||||
}
|
||||
}
|
||||
_isSelecting = false;
|
||||
}
|
||||
_isSelecting = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EnergyCountPeakFitView::addSelectionRect(const QRectF &plotRect)
|
||||
void EnergyCountPeakFitView::addSelectionRect(const QRectF& plotRect)
|
||||
{
|
||||
PlotRectItem* rectItem = new PlotRectItem("Selection");
|
||||
rectItem->setAxes(QwtPlot::xBottom, QwtPlot::yLeft);
|
||||
rectItem->setRect(plotRect);
|
||||
// 设置填充为透明(无填充)
|
||||
rectItem->setBrush(QBrush(Qt::transparent)); // 或 Qt::NoBrush
|
||||
// 设置边框颜色为红色,线宽2
|
||||
rectItem->setPen(QPen(Qt::red, 2));
|
||||
rectItem->attach(_plot);
|
||||
_selectionRectItems.append(rectItem);
|
||||
_plot->replot();
|
||||
rectItem->setAxes(QwtPlot::xBottom, QwtPlot::yLeft);
|
||||
rectItem->setRect(plotRect);
|
||||
// 设置填充为透明(无填充)
|
||||
rectItem->setBrush(QBrush(Qt::transparent)); // 或 Qt::NoBrush
|
||||
// 设置边框颜色为红色,线宽2
|
||||
rectItem->setPen(QPen(Qt::red, 2));
|
||||
rectItem->attach(_plot);
|
||||
_selectionRectItems.append(rectItem);
|
||||
_plot->replot();
|
||||
}
|
||||
|
||||
void EnergyCountPeakFitView::fadeSelectionRectBorders()
|
||||
{
|
||||
for (PlotRectItem* item : _selectionRectItems) {
|
||||
if (item) {
|
||||
QPen fadedPen(Qt::red, 1, Qt::DashLine); // 可根据原样式调整
|
||||
QPen fadedPen(Qt::red, 1, Qt::DashLine); // 可根据原样式调整
|
||||
item->setPen(fadedPen);
|
||||
}
|
||||
}
|
||||
_plot->replot();
|
||||
}
|
||||
|
||||
QList<PeakFitResult> EnergyCountPeakFitView::performPeakFitting(const QVector<double> &x, const QVector<double> &y, const arma::vec* userP0)
|
||||
QList<PeakFitResult> EnergyCountPeakFitView::performPeakFitting(const QVector<double>& x, const QVector<double>& y, const arma::vec* userP0)
|
||||
{
|
||||
// 清除之前的拟合曲线(每次拟合全新绘制)
|
||||
// clearFitCurves();
|
||||
|
||||
// clearFitCurves();
|
||||
|
||||
QList<PeakFitResult> results;
|
||||
if (x.size() != y.size() || x.size() < 3)
|
||||
{
|
||||
qDebug() << QStringLiteral(u"数据长度不足");
|
||||
return results;
|
||||
}
|
||||
if (x.size() != y.size() || x.size() < 3) {
|
||||
qDebug() << QStringLiteral(u"数据长度不足");
|
||||
return results;
|
||||
}
|
||||
|
||||
// 转换为 Armadillo 向量
|
||||
arma::vec armaX(x.size()), armaY(y.size());
|
||||
for (int i = 0; i < x.size(); ++i) {
|
||||
armaX(i) = x[i];
|
||||
armaY(i) = y[i];
|
||||
}
|
||||
// 转换为 Armadillo 向量
|
||||
arma::vec armaX(x.size()), armaY(y.size());
|
||||
for (int i = 0; i < x.size(); ++i) {
|
||||
armaX(i) = x[i];
|
||||
armaY(i) = y[i];
|
||||
}
|
||||
|
||||
const int step_w = 20;
|
||||
if (armaY.n_elem < step_w) {
|
||||
qDebug() << QStringLiteral(u"ROI 数据点太少,跳过寻峰。");
|
||||
return results;
|
||||
}
|
||||
if (arma::all(armaY == 0)) {
|
||||
qDebug() << QStringLiteral(u"ROI 计数全为零,跳过寻峰。");
|
||||
return results;
|
||||
}
|
||||
const int step_w = 20;
|
||||
if (armaY.n_elem < step_w) {
|
||||
qDebug() << QStringLiteral(u"ROI 数据点太少,跳过寻峰。");
|
||||
return results;
|
||||
}
|
||||
if (arma::all(armaY == 0)) {
|
||||
qDebug() << QStringLiteral(u"ROI 计数全为零,跳过寻峰。");
|
||||
return results;
|
||||
}
|
||||
|
||||
// 构建两列矩阵:第一列为能量,第二列为计数
|
||||
arma::mat spec_data(armaX.n_rows, 2);
|
||||
spec_data.col(0) = armaX;
|
||||
spec_data.col(1) = armaY;
|
||||
// 构建两列矩阵:第一列为能量,第二列为计数
|
||||
arma::mat spec_data(armaX.n_rows, 2);
|
||||
spec_data.col(0) = armaX;
|
||||
spec_data.col(1) = armaY;
|
||||
|
||||
FindPeaksBySvd peakFinder;
|
||||
std::vector<FindPeaksBySvd::PeakInfo> peaks;
|
||||
try {
|
||||
peaks = peakFinder.FindPeaks(spec_data, step_w);
|
||||
} catch (const std::string& s) {
|
||||
qDebug() << QStringLiteral(u"FindPeaks 异常:") << s.c_str();
|
||||
return results;
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << QStringLiteral(u"FindPeaks 异常:") << e.what();
|
||||
return results;
|
||||
} catch (...) {
|
||||
qDebug() << QStringLiteral(u"FindPeaks 未知异常");
|
||||
return results;
|
||||
}
|
||||
FindPeaksBySvd peakFinder;
|
||||
std::vector<FindPeaksBySvd::PeakInfo> peaks;
|
||||
try {
|
||||
peaks = peakFinder.FindPeaks(spec_data, step_w);
|
||||
} catch (const std::string& s) {
|
||||
qDebug() << QStringLiteral(u"FindPeaks 异常:") << s.c_str();
|
||||
return results;
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << QStringLiteral(u"FindPeaks 异常:") << e.what();
|
||||
return results;
|
||||
} catch (...) {
|
||||
qDebug() << QStringLiteral(u"FindPeaks 未知异常");
|
||||
return results;
|
||||
}
|
||||
|
||||
if (peaks.empty()) {
|
||||
qDebug() << QStringLiteral(u"未检测到峰。");
|
||||
return results;
|
||||
}
|
||||
if (peaks.empty()) {
|
||||
qDebug() << QStringLiteral(u"未检测到峰。");
|
||||
return results;
|
||||
}
|
||||
|
||||
// 选择最重要的峰(例如幅值最大的峰)
|
||||
auto bestPeak = *std::max_element(peaks.begin(), peaks.end(),
|
||||
[](const FindPeaksBySvd::PeakInfo& a, const FindPeaksBySvd::PeakInfo& b) {
|
||||
return a.height < b.height;
|
||||
});
|
||||
int idxCenter = bestPeak.pos;
|
||||
if (idxCenter < 0 || idxCenter >= x.size())
|
||||
return results;
|
||||
double centerEnergy = armaX(idxCenter);
|
||||
// 选择最重要的峰(例如幅值最大的峰)
|
||||
auto bestPeak = *std::max_element(peaks.begin(), peaks.end(),
|
||||
[](const FindPeaksBySvd::PeakInfo& a, const FindPeaksBySvd::PeakInfo& b) {
|
||||
return a.height < b.height;
|
||||
});
|
||||
int idxCenter = bestPeak.pos;
|
||||
if (idxCenter < 0 || idxCenter >= x.size())
|
||||
return results;
|
||||
double centerEnergy = armaX(idxCenter);
|
||||
|
||||
const double fitRangeEnergy = 15.0;
|
||||
// 提取局部数据
|
||||
QVector<double> localX, localY;
|
||||
for (int i = 0; i < x.size(); ++i) {
|
||||
if (x[i] >= centerEnergy - fitRangeEnergy && x[i] <= centerEnergy + fitRangeEnergy) {
|
||||
localX.push_back(x[i]);
|
||||
localY.push_back(y[i]);
|
||||
}
|
||||
}
|
||||
if (localX.size() < 5) {
|
||||
qDebug() << QStringLiteral(u"局部数据点不足5,跳过拟合");
|
||||
return results;
|
||||
}
|
||||
const double fitRangeEnergy = 15.0;
|
||||
// 提取局部数据
|
||||
QVector<double> localX, localY;
|
||||
for (int i = 0; i < x.size(); ++i) {
|
||||
if (x[i] >= centerEnergy - fitRangeEnergy && x[i] <= centerEnergy + fitRangeEnergy) {
|
||||
localX.push_back(x[i]);
|
||||
localY.push_back(y[i]);
|
||||
}
|
||||
}
|
||||
if (localX.size() < 5) {
|
||||
qDebug() << QStringLiteral(u"局部数据点不足5,跳过拟合");
|
||||
return results;
|
||||
}
|
||||
|
||||
arma::vec xLocal(localX.size()), yLocal(localY.size());
|
||||
for (int i = 0; i < localX.size(); ++i) {
|
||||
xLocal(i) = localX[i];
|
||||
yLocal(i) = localY[i];
|
||||
}
|
||||
arma::vec xLocal(localX.size()), yLocal(localY.size());
|
||||
for (int i = 0; i < localX.size(); ++i) {
|
||||
xLocal(i) = localX[i];
|
||||
yLocal(i) = localY[i];
|
||||
}
|
||||
|
||||
arma::vec p0;
|
||||
if (userP0 && userP0->n_elem == 6) {
|
||||
p0 = *userP0;
|
||||
} else {
|
||||
try {
|
||||
p0 = EstimatePhotonPeakModelInitialParams(xLocal, yLocal);
|
||||
} catch (...) {
|
||||
qDebug() << QStringLiteral(u"初始参数估算失败,跳过拟合");
|
||||
return results;
|
||||
}
|
||||
}
|
||||
arma::vec p0;
|
||||
if (userP0 && userP0->n_elem == 6) {
|
||||
p0 = *userP0;
|
||||
} else {
|
||||
try {
|
||||
p0 = EstimatePhotonPeakModelInitialParams(xLocal, yLocal);
|
||||
} catch (...) {
|
||||
qDebug() << QStringLiteral(u"初始参数估算失败,跳过拟合");
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
arma::vec p_fit;
|
||||
try {
|
||||
p_fit = NolinearLeastSquaresCurveFit::Lsqcurvefit(PhotonPeakModel, xLocal, yLocal, p0);
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << QStringLiteral(u"拟合失败:") << e.what();
|
||||
return results;
|
||||
}
|
||||
arma::vec p_fit;
|
||||
try {
|
||||
p_fit = NolinearLeastSquaresCurveFit::Lsqcurvefit(PhotonPeakModel, xLocal, yLocal, p0);
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << QStringLiteral(u"拟合失败:") << e.what();
|
||||
return results;
|
||||
}
|
||||
|
||||
double sigma = p_fit(1);
|
||||
double fwhm = sigma * 2.355;
|
||||
double sigma = p_fit(1);
|
||||
double fwhm = sigma * 2.355;
|
||||
|
||||
AdaptiveSimpsonIntegrate::FitFunction fitFunc;
|
||||
fitFunc.A = p_fit(0);
|
||||
fitFunc.delt= p_fit(1);
|
||||
fitFunc.H = p_fit(2);
|
||||
fitFunc.W = p_fit(3);
|
||||
fitFunc.C = p_fit(4);
|
||||
fitFunc.P = p_fit(5);
|
||||
double lower = fitFunc.P - 3.0 * fitFunc.delt;
|
||||
double upper = fitFunc.P + 3.0 * fitFunc.delt;
|
||||
double area = AdaptiveSimpsonIntegrate::integrate(fitFunc, lower, upper);
|
||||
AdaptiveSimpsonIntegrate::FitFunction fitFunc;
|
||||
fitFunc.A = p_fit(0);
|
||||
fitFunc.delt = p_fit(1);
|
||||
fitFunc.H = p_fit(2);
|
||||
fitFunc.W = p_fit(3);
|
||||
fitFunc.C = p_fit(4);
|
||||
fitFunc.P = p_fit(5);
|
||||
double lower = fitFunc.P - 3.0 * fitFunc.delt;
|
||||
double upper = fitFunc.P + 3.0 * fitFunc.delt;
|
||||
double area = AdaptiveSimpsonIntegrate::integrate(fitFunc, lower, upper);
|
||||
|
||||
PeakFitResult result;
|
||||
result.center = p_fit(5);
|
||||
result.amplitude = p_fit(0);
|
||||
result.sigma = p_fit(1);
|
||||
result.fwhm = fwhm;
|
||||
result.area = area;
|
||||
result.baseline = p_fit(4);
|
||||
result.sigmoidH = p_fit(2);
|
||||
result.sigmoidW = p_fit(3);
|
||||
PeakFitResult result;
|
||||
result.center = p_fit(5);
|
||||
result.amplitude = p_fit(0);
|
||||
result.sigma = p_fit(1);
|
||||
result.fwhm = fwhm;
|
||||
result.area = area;
|
||||
result.baseline = p_fit(4);
|
||||
result.sigmoidH = p_fit(2);
|
||||
result.sigmoidW = p_fit(3);
|
||||
|
||||
double xMinPlot = result.center - 3 * result.sigma;
|
||||
double xMaxPlot = result.center + 3 * result.sigma;
|
||||
xMinPlot = qMax(xMinPlot, localX.first());
|
||||
xMaxPlot = qMin(xMaxPlot, localX.last());
|
||||
QwtPlotCurve* fitCurve = createFitCurve(result, xMinPlot, xMaxPlot, QStringLiteral(u"拟合数据"));
|
||||
fitCurve->setPen(QPen(Qt::blue, 2));
|
||||
_fitCurves.append(fitCurve);
|
||||
double xMinPlot = result.center - 3 * result.sigma;
|
||||
double xMaxPlot = result.center + 3 * result.sigma;
|
||||
xMinPlot = qMax(xMinPlot, localX.first());
|
||||
xMaxPlot = qMin(xMaxPlot, localX.last());
|
||||
QwtPlotCurve* fitCurve = createFitCurve(result, xMinPlot, xMaxPlot, QStringLiteral(u"拟合数据"));
|
||||
fitCurve->setPen(QPen(Qt::blue, 2));
|
||||
_fitCurves.append(fitCurve);
|
||||
|
||||
results.append(result);
|
||||
_plot->replot();
|
||||
results.append(result);
|
||||
_plot->replot();
|
||||
|
||||
_lastFitResult = result;
|
||||
_lastFitParams = p_fit;
|
||||
_lastXMin = xMinPlot;
|
||||
_lastXMax = xMaxPlot;
|
||||
_hasLastFit = true;
|
||||
return results;
|
||||
_lastFitResult = result;
|
||||
_lastFitParams = p_fit;
|
||||
_lastXMin = xMinPlot;
|
||||
_lastXMax = xMaxPlot;
|
||||
_hasLastFit = true;
|
||||
return results;
|
||||
}
|
||||
|
||||
QwtPlotCurve *EnergyCountPeakFitView::createFitCurve(const PeakFitResult &result, double xMin, double xMax, const QString &name)
|
||||
QwtPlotCurve* EnergyCountPeakFitView::createFitCurve(const PeakFitResult& result, double xMin, double xMax, const QString& name)
|
||||
{
|
||||
const int numPoints = 200;
|
||||
QVector<double> xs, ys;
|
||||
double step = (xMax - xMin) / (numPoints - 1);
|
||||
QVector<double> xs, ys;
|
||||
double step = (xMax - xMin) / (numPoints - 1);
|
||||
|
||||
arma::vec p(6);
|
||||
p(0) = result.amplitude;
|
||||
p(1) = result.sigma;
|
||||
p(2) = result.sigmoidH;
|
||||
p(3) = result.sigmoidW;
|
||||
p(4) = result.baseline;
|
||||
p(5) = result.center;
|
||||
arma::vec p(6);
|
||||
p(0) = result.amplitude;
|
||||
p(1) = result.sigma;
|
||||
p(2) = result.sigmoidH;
|
||||
p(3) = result.sigmoidW;
|
||||
p(4) = result.baseline;
|
||||
p(5) = result.center;
|
||||
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
double x = xMin + i * step;
|
||||
xs.append(x);
|
||||
double y = PhotonPeakModel(x, p);
|
||||
ys.append(y);
|
||||
}
|
||||
QwtPlotCurve* curve = new QwtPlotCurve(QStringLiteral(u"拟合数据"));
|
||||
curve->setPen(QPen(Qt::blue, 2));
|
||||
curve->setSamples(xs, ys);
|
||||
curve->attach(_plot);
|
||||
return curve;
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
double x = xMin + i * step;
|
||||
xs.append(x);
|
||||
double y = PhotonPeakModel(x, p);
|
||||
ys.append(y);
|
||||
}
|
||||
QwtPlotCurve* curve = new QwtPlotCurve(QStringLiteral(u"拟合数据"));
|
||||
curve->setPen(QPen(Qt::blue, 2));
|
||||
curve->setSamples(xs, ys);
|
||||
curve->attach(_plot);
|
||||
return curve;
|
||||
}
|
||||
|
||||
|
||||
void EnergyCountPeakFitView::clearFitCurves()
|
||||
{
|
||||
for (QwtPlotCurve* curve : _fitCurves) {
|
||||
|
|
@ -754,7 +743,7 @@ void EnergyCountPeakFitView::saveCurrentFitToHistory()
|
|||
|
||||
void EnergyCountPeakFitView::displayFitFromHistory(const PeakFitHistoryItem& item)
|
||||
{
|
||||
// clearFitCurves();
|
||||
// clearFitCurves();
|
||||
|
||||
arma::vec p(6);
|
||||
p(0) = item.amplitude;
|
||||
|
|
@ -782,12 +771,11 @@ void EnergyCountPeakFitView::displayFitFromHistory(const PeakFitHistoryItem& ite
|
|||
QwtPlotMarker* infoMarker = new QwtPlotMarker();
|
||||
infoMarker->setValue(item.center, 0);
|
||||
infoMarker->setLabel(QStringLiteral(u"历史峰: %1 keV\nFWHM: %2")
|
||||
.arg(item.center, 0, 'f', 2)
|
||||
.arg(item.fwhm, 0, 'f', 2));
|
||||
.arg(item.center, 0, 'f', 2)
|
||||
.arg(item.fwhm, 0, 'f', 2));
|
||||
infoMarker->setLabelAlignment(Qt::AlignTop | Qt::AlignRight);
|
||||
infoMarker->attach(_plot);
|
||||
|
||||
|
||||
_plot->replot();
|
||||
}
|
||||
|
||||
|
|
@ -812,10 +800,10 @@ void EnergyCountPeakFitView::onActionShowFitHistory()
|
|||
QListWidget* listWidget = new QListWidget(&dlg);
|
||||
for (const auto& item : _fitHistoryList) {
|
||||
QString text = QStringLiteral(u"%1 峰中心: %2 keV FWHM: %3 面积: %4")
|
||||
.arg(item.timestamp.toString("yyyy-MM-dd hh:mm:ss"))
|
||||
.arg(item.center, 0, 'f', 2)
|
||||
.arg(item.fwhm, 0, 'f', 2)
|
||||
.arg(item.area, 0, 'f', 0);
|
||||
.arg(item.timestamp.toString("yyyy-MM-dd hh:mm:ss"))
|
||||
.arg(item.center, 0, 'f', 2)
|
||||
.arg(item.fwhm, 0, 'f', 2)
|
||||
.arg(item.area, 0, 'f', 0);
|
||||
listWidget->addItem(text);
|
||||
}
|
||||
layout->addWidget(listWidget);
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@
|
|||
#include "EnergyScaleForm.h"
|
||||
#include "MeasureAnalysisHistoryForm.h"
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
#include "MeasureDeviceParamsCfgForm.h"
|
||||
#include "NewMeasureAnalysisDlg.h"
|
||||
#include "MeasureAnalysisView.h"
|
||||
#include "MeasureAnalysisTreeView.h"
|
||||
#include "GlobalDefine.h"
|
||||
#include "DeviceParameterConfig.h"
|
||||
#include "DeviceParamsManagerDlg.h"
|
||||
#include "NuclideLib.h"
|
||||
|
||||
using namespace ads;
|
||||
|
||||
MainWindow* MainWindow::_s_main_win = nullptr;
|
||||
|
|
@ -222,16 +222,7 @@ void MainWindow::initAction()
|
|||
});
|
||||
connect(ui->action_manage_measurement_analysis, &QAction::triggered, this->_action_central_dock_widget, &QAction::triggered);
|
||||
connect(ui->action_device_config_mrg, &QAction::triggered, []() {
|
||||
QDialog device_cfg_mrg_dlg;
|
||||
device_cfg_mrg_dlg.setObjectName("MeasureDeviceParamsCfgFormDlg");
|
||||
device_cfg_mrg_dlg.setWindowTitle(QStringLiteral(u"测量设备参数配置管理"));
|
||||
device_cfg_mrg_dlg.setWindowFlags(device_cfg_mrg_dlg.windowFlags() | Qt::WindowMaximizeButtonHint);
|
||||
// MeasureDeviceParamsCfgForm* measure_dev_params_cfg_form = new MeasureDeviceParamsCfgForm(&device_cfg_mrg_dlg);
|
||||
DeviceParameterConfig * measure_dev_params_cfg_form = new DeviceParameterConfig(&device_cfg_mrg_dlg);
|
||||
QHBoxLayout* hlayout = new QHBoxLayout;
|
||||
hlayout->addWidget(measure_dev_params_cfg_form);
|
||||
device_cfg_mrg_dlg.setLayout(hlayout);
|
||||
device_cfg_mrg_dlg.exec();
|
||||
DeviceParamsManagerDlg().exec();
|
||||
});
|
||||
connect(ui->action_energy_scale_mrg, &QAction::triggered, []() {
|
||||
QDialog energy_scale_mrg_dlg;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void MeasureAnalysisHistoryForm::loadHistoryInfo(const QString &history_name)
|
|||
if (!projects_dir.exists()) {
|
||||
return;
|
||||
}
|
||||
QList<QString> project_dirs = projects_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time);
|
||||
QList<QString> project_dirs = projects_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::Time);
|
||||
for (const QString& project_dir : project_dirs) {
|
||||
QDir project_dir_path(projects_dir.filePath(project_dir));
|
||||
if (project_dir_path.exists()) {
|
||||
|
|
@ -147,7 +147,7 @@ void MeasureAnalysisHistoryForm::onRemoveSelectedProject()
|
|||
}
|
||||
}
|
||||
if (selected_project_list.isEmpty()) {
|
||||
QMessageBox::information(this, QStringLiteral(u"确认"), QStringLiteral(u"请选择想要删除的测量分析项目!"));
|
||||
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择想要删除的测量分析项目!"));
|
||||
return;
|
||||
}
|
||||
if (QMessageBox::No == QMessageBox::question(this, QStringLiteral(u"确认"), QStringLiteral(u"是否删除选择的测量分析项目?"))) {
|
||||
|
|
|
|||
|
|
@ -548,6 +548,7 @@ bool MeasureAnalysisProjectModelList::RmProjectModel(const QString& project_name
|
|||
return false;
|
||||
}
|
||||
}
|
||||
emit removedProjectModel(project_name);
|
||||
if (_project_models.contains(project_name)) {
|
||||
delete _project_models[project_name];
|
||||
_project_models.remove(project_name);
|
||||
|
|
@ -557,7 +558,6 @@ bool MeasureAnalysisProjectModelList::RmProjectModel(const QString& project_name
|
|||
const QString& project_name = project_model->GetProjectName();
|
||||
SetCurrentProjectModel(project_name);
|
||||
}
|
||||
emit removedProjectModel(project_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
#include "MeasureDeviceParamsCfgForm.h"
|
||||
#include "ui_MeasureDeviceParamsCfgForm.h"
|
||||
|
||||
MeasureDeviceParamsCfgForm::MeasureDeviceParamsCfgForm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::MeasureDeviceParamsCfgForm)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
MeasureDeviceParamsCfgForm::~MeasureDeviceParamsCfgForm()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef MEASUREDEVICEPARAMSCFGFORM_H
|
||||
#define MEASUREDEVICEPARAMSCFGFORM_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class MeasureDeviceParamsCfgForm;
|
||||
}
|
||||
|
||||
class MeasureDeviceParamsCfgForm : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MeasureDeviceParamsCfgForm(QWidget *parent = nullptr);
|
||||
~MeasureDeviceParamsCfgForm();
|
||||
|
||||
private:
|
||||
Ui::MeasureDeviceParamsCfgForm *ui;
|
||||
};
|
||||
|
||||
#endif // MEASUREDEVICEPARAMSCFGFORM_H
|
||||
|
|
@ -1,317 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MeasureDeviceParamsCfgForm</class>
|
||||
<widget class="QWidget" name="MeasureDeviceParamsCfgForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1453</width>
|
||||
<height>806</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>测量设备参数配置</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>设备参数配置列表</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listw_device_cfg">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_add_cfg_list_item">
|
||||
<property name="text">
|
||||
<string>添加</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_remove_cfg_list_item">
|
||||
<property name="text">
|
||||
<string>删除</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>配置命名:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_cfg_name"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_save_to_project">
|
||||
<property name="text">
|
||||
<string>保存到测量分析</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_save_to_sys">
|
||||
<property name="text">
|
||||
<string>保存到设备参数配置管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>备注说明:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_description">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tablew_params_cfg">
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道1</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道2</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道3</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道4</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道5</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道6</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道7</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道8</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道9</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道10</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道11</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道12</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道13</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道14</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道15</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道16</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道17</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道18</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道19</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道20</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道21</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>通道22</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>时间常数</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>上升时间</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>平顶时间</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>触发阈值</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>直流偏移</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>恢复速度</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>滤波参数</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>输入信号正负</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>LFR</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>保护时间</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>硬件增益</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>软件增益</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>谱线道数</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
143
src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp
Normal file
143
src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#include "DeviceParamsManagerDlg.h"
|
||||
#include "ui_DeviceParamsManagerDlg.h"
|
||||
#include <QDir>
|
||||
#include "GlobalDefine.h"
|
||||
#include "DeviceParamsSaveToSysDlg.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
DeviceParamsManagerDlg::DeviceParamsManagerDlg(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::DeviceParamsManagerDlg)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
this->setWindowFlags(this->windowFlags() | Qt::WindowMinMaxButtonsHint);
|
||||
|
||||
scanParamsCfgFiles();
|
||||
|
||||
connect(ui->listw_cfg_list, &QListWidget::currentItemChanged, this, &DeviceParamsManagerDlg::onCfgListCurrentItemChanged);
|
||||
connect(ui->btn_new, &QPushButton::clicked, this, &DeviceParamsManagerDlg::onBtnNew);
|
||||
connect(ui->btn_delete, &QPushButton::clicked, this, &DeviceParamsManagerDlg::onBtnDelete);
|
||||
connect(ui->btn_save, &QPushButton::clicked, this, &DeviceParamsManagerDlg::onBtnSave);
|
||||
}
|
||||
|
||||
DeviceParamsManagerDlg::~DeviceParamsManagerDlg()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DeviceParamsManagerDlg::scanParamsCfgFiles()
|
||||
{
|
||||
ui->params_table_form->SetButtonEnable(false);
|
||||
ui->listw_cfg_list->clear();
|
||||
// 遍历可执行文件目录下Projects目录下的所有文件夹,找出所有项目文件夹下的.msproject文件
|
||||
const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams");
|
||||
QDir device_params_dir(device_params_dir_path);
|
||||
if (!device_params_dir.exists(device_params_dir_path)) {
|
||||
LOG_WARN(QStringLiteral(u"系统测量参数配置管理目录不存在:%1").arg(device_params_dir_path));
|
||||
return;
|
||||
}
|
||||
QList<QString> ms_cfg_basenames = device_params_dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::Time);
|
||||
for (const QString& ms_cfg_basename : ms_cfg_basenames) {
|
||||
const QString& ms_cfg_filename = device_params_dir.filePath(ms_cfg_basename);
|
||||
QFileInfo ms_cfg_file_info(ms_cfg_filename);
|
||||
if ("mscfg" == ms_cfg_file_info.suffix()) {
|
||||
QListWidgetItem* item = new QListWidgetItem(ms_cfg_file_info.baseName());
|
||||
item->setData(Qt::UserRole, ms_cfg_filename);
|
||||
ui->listw_cfg_list->addItem(item);
|
||||
}
|
||||
}
|
||||
const QString cfg_name = ui->linedit_cfg_name->text();
|
||||
if (!cfg_name.isEmpty()) {
|
||||
QList<QListWidgetItem*> items = ui->listw_cfg_list->findItems(cfg_name, Qt::MatchExactly);
|
||||
QListWidgetItem* current_item = items.first();
|
||||
if (current_item) {
|
||||
ui->listw_cfg_list->setCurrentItem(current_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParamsManagerDlg::onBtnNew()
|
||||
{
|
||||
DeviceParamsSaveToSysDlg params_save_to_sys_dlg;
|
||||
if (QDialog::Accepted == params_save_to_sys_dlg.exec()) {
|
||||
const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams");
|
||||
const QString cfg_name = params_save_to_sys_dlg.GetCfgName();
|
||||
const QString cfg_description = params_save_to_sys_dlg.GetCfgDescription();
|
||||
const QString params_cfg_filename = QDir(device_params_dir_path).filePath(cfg_name) + ".mscfg";
|
||||
if (ui->params_table_form->SaveSelectedChannelConfig(params_cfg_filename, cfg_name, cfg_description)) {
|
||||
QListWidgetItem* item = new QListWidgetItem(cfg_name);
|
||||
item->setData(Qt::UserRole, params_cfg_filename);
|
||||
ui->listw_cfg_list->addItem(item);
|
||||
ui->listw_cfg_list->setCurrentItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParamsManagerDlg::onBtnDelete()
|
||||
{
|
||||
QListWidgetItem *current = ui->listw_cfg_list->currentItem();
|
||||
if (current) {
|
||||
const QString& ms_cfg_filename = current->data(Qt::UserRole).toString();
|
||||
if (!ms_cfg_filename.isEmpty()) {
|
||||
if (QMessageBox::No == QMessageBox::question(this, QStringLiteral(u"确认"), QStringLiteral(u"是否删除选择的测量参数配置?"))) {
|
||||
return;
|
||||
}
|
||||
QFile ms_cfg_file(ms_cfg_filename);
|
||||
if (!ms_cfg_file.remove()) {
|
||||
LOG_WARN(QStringLiteral(u"删除设备测量参数配置[%1]失败: %2").arg(current->text()).arg(ms_cfg_file.errorString()));
|
||||
} else {
|
||||
ui->listw_cfg_list->removeItemWidget(current);
|
||||
ui->linedit_cfg_name->clear();
|
||||
ui->pte_description->clear();
|
||||
ui->params_table_form->ClearParamsTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParamsManagerDlg::onBtnSave()
|
||||
{
|
||||
const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams");
|
||||
const QString cfg_name = ui->linedit_cfg_name->text();
|
||||
if (cfg_name.isEmpty()) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量参数配置名称不能为空!"));
|
||||
return;
|
||||
}
|
||||
const QString cfg_description = ui->pte_description->toPlainText();
|
||||
const QString cfg_filename = QDir(device_params_dir_path).filePath(cfg_name) + ".mscfg";
|
||||
if (QFile::exists(cfg_filename)) {
|
||||
QListWidgetItem *current = ui->listw_cfg_list->currentItem();
|
||||
if (current) {
|
||||
const QString& ms_cfg_filename = current->data(Qt::UserRole).toString();
|
||||
if (!ms_cfg_filename.isEmpty()) {
|
||||
QFile ms_cfg_file(ms_cfg_filename);
|
||||
if (!ms_cfg_file.remove()) {
|
||||
LOG_WARN(QStringLiteral(u"删除设备测量参数配置[%1]失败: %2").arg(current->text()).arg(ms_cfg_file.errorString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ui->params_table_form->SaveSelectedChannelConfig(cfg_filename, cfg_name, cfg_description)) {
|
||||
QListWidgetItem* current = ui->listw_cfg_list->currentItem();
|
||||
if (current) {
|
||||
current->setText(cfg_name);
|
||||
current->setData(Qt::UserRole, cfg_filename);
|
||||
}
|
||||
}
|
||||
this->scanParamsCfgFiles();
|
||||
}
|
||||
|
||||
void DeviceParamsManagerDlg::onCfgListCurrentItemChanged(QListWidgetItem *current)
|
||||
{
|
||||
if (current) {
|
||||
const QString& ms_cfg_filename = current->data(Qt::UserRole).toString();
|
||||
if (!ms_cfg_filename.isEmpty()) {
|
||||
ui->params_table_form->SetConfigFilename(ms_cfg_filename);
|
||||
ui->linedit_cfg_name->clear();
|
||||
ui->pte_description->clear();
|
||||
ui->linedit_cfg_name->setText(ui->params_table_form->GetConfigName());
|
||||
ui->pte_description->setPlainText(ui->params_table_form->GetConfigDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h
Normal file
33
src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef DEVICEPARAMSMANAGERDLG_H
|
||||
#define DEVICEPARAMSMANAGERDLG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class DeviceParamsManagerDlg;
|
||||
}
|
||||
|
||||
class QListWidgetItem;
|
||||
|
||||
class DeviceParamsManagerDlg : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeviceParamsManagerDlg(QWidget *parent = nullptr);
|
||||
~DeviceParamsManagerDlg();
|
||||
|
||||
private:
|
||||
void scanParamsCfgFiles();
|
||||
|
||||
private slots:
|
||||
void onBtnNew();
|
||||
void onBtnDelete();
|
||||
void onBtnSave();
|
||||
void onCfgListCurrentItemChanged(QListWidgetItem *current);
|
||||
|
||||
private:
|
||||
Ui::DeviceParamsManagerDlg *ui;
|
||||
};
|
||||
|
||||
#endif // DEVICEPARAMSMANAGERDLG_H
|
||||
143
src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui
Normal file
143
src/MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DeviceParamsManagerDlg</class>
|
||||
<widget class="QDialog" name="DeviceParamsManagerDlg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1075</width>
|
||||
<height>712</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>设备测量参数管理</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>设备测量参数配置列表</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listw_cfg_list">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_new">
|
||||
<property name="text">
|
||||
<string>新建配置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_delete">
|
||||
<property name="text">
|
||||
<string>删除配置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>测量参数配置名称:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="linedit_cfg_name"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_save">
|
||||
<property name="text">
|
||||
<string>保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>测量参数配置说明:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="pte_description">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="DeviceParamsTableForm" name="params_table_form" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DeviceParamsTableForm</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>DeviceParamsTableForm.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#include "DeviceParamsSaveToSysDlg.h"
|
||||
#include "ui_DeviceParamsSaveToSysDlg.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
|
||||
DeviceParamsSaveToSysDlg::DeviceParamsSaveToSysDlg(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::DeviceParamsSaveToSysDlg)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
connect(ui->btn_cancel, &QPushButton::clicked, this, &DeviceParamsSaveToSysDlg::reject);
|
||||
connect(ui->btn_ok, &QPushButton::clicked, this, &DeviceParamsSaveToSysDlg::onBtnOkClicked);
|
||||
}
|
||||
|
||||
DeviceParamsSaveToSysDlg::~DeviceParamsSaveToSysDlg()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString DeviceParamsSaveToSysDlg::GetCfgName()
|
||||
{
|
||||
return ui->linedit_name->text();
|
||||
}
|
||||
|
||||
QString DeviceParamsSaveToSysDlg::GetCfgDescription()
|
||||
{
|
||||
return ui->pte_description->toPlainText();
|
||||
}
|
||||
|
||||
void DeviceParamsSaveToSysDlg::onBtnOkClicked()
|
||||
{
|
||||
const QString& cfg_name = ui->linedit_name->text();
|
||||
if (cfg_name.isEmpty()) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量参数配置名称不能为空!"));
|
||||
return;
|
||||
}
|
||||
const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams");
|
||||
const QString ms_cfg_name = cfg_name + QString(".mscfg");
|
||||
if (QDir(device_params_dir_path).exists(ms_cfg_name)) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量参数配置名称\"%1\"已存在!").arg(cfg_name));
|
||||
return;
|
||||
}
|
||||
this->accept();
|
||||
}
|
||||
28
src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h
Normal file
28
src/MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef DEVICEPARAMSSAVETOSYSDLG_H
|
||||
#define DEVICEPARAMSSAVETOSYSDLG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class DeviceParamsSaveToSysDlg;
|
||||
}
|
||||
|
||||
class DeviceParamsSaveToSysDlg : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeviceParamsSaveToSysDlg(QWidget *parent = nullptr);
|
||||
~DeviceParamsSaveToSysDlg();
|
||||
|
||||
QString GetCfgName();
|
||||
QString GetCfgDescription();
|
||||
|
||||
private slots:
|
||||
void onBtnOkClicked();
|
||||
|
||||
private:
|
||||
Ui::DeviceParamsSaveToSysDlg *ui;
|
||||
};
|
||||
|
||||
#endif // DEVICEPARAMSSAVETOSYSDLG_H
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DeviceParamsSaveToSysDlg</class>
|
||||
<widget class="QDialog" name="DeviceParamsSaveToSysDlg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>512</width>
|
||||
<height>229</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>测量设备参数信息</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>测量参数配置名称:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="linedit_name"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>测量参数配置说明:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="pte_description"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_ok">
|
||||
<property name="text">
|
||||
<string>保存到系统</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_cancel">
|
||||
<property name="text">
|
||||
<string>取消</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -9,6 +9,17 @@
|
|||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMessageBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QDir>
|
||||
#include "DeviceParamsSaveToSysDlg.h"
|
||||
|
||||
static QStringList s_addr_count_list { "256", "512", "1024", "2048", "4096", "8192", "16384" };
|
||||
static QMap<int, QString> s_transfer_mode_list {
|
||||
{ 1, QStringLiteral(u"波形模式") },
|
||||
{ 2, QStringLiteral(u"ADC模式") },
|
||||
{ 3, QStringLiteral(u"粒子模式") }
|
||||
};
|
||||
static QStringList s_device_gain_list { "1", "2", "4", "8", "16" };
|
||||
|
||||
DeviceParamsItemDelegate::DeviceParamsItemDelegate(QObject* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
|
|
@ -21,52 +32,66 @@ QWidget* DeviceParamsItemDelegate::createEditor(QWidget* parent, const QStyleOpt
|
|||
int col = index.column();
|
||||
switch (col) {
|
||||
case 1: { // 多道分辨率
|
||||
QStringList value_list { "256", "512", "1024", "2048", "4096", "8192", "16384" };
|
||||
QComboBox *combobox = new QComboBox(parent);
|
||||
for (int index = 0; index < value_list.size(); ++index) {
|
||||
QString value = value_list.at(index);
|
||||
for (int index = 0; index < s_addr_count_list.size(); ++index) {
|
||||
QString value = s_addr_count_list.at(index);
|
||||
combobox->addItem(value);
|
||||
}
|
||||
editor = combobox;
|
||||
} break;
|
||||
case 2: { // 硬件增益
|
||||
QStringList value_list { "1", "2", "4", "8", "16" };
|
||||
case 2: { // 数据模式
|
||||
QComboBox *combobox = new QComboBox(parent);
|
||||
for (int index = 0; index < value_list.size(); ++index) {
|
||||
QString value = value_list.at(index);
|
||||
QList<int> transfer_mode_list = s_transfer_mode_list.keys();
|
||||
qSort(transfer_mode_list.rbegin(), transfer_mode_list.rend());
|
||||
foreach (int transfer_mode, transfer_mode_list) {
|
||||
combobox->addItem(s_transfer_mode_list.value(transfer_mode), transfer_mode);
|
||||
}
|
||||
editor = combobox;
|
||||
} break;
|
||||
case 3: { // 硬件增益
|
||||
QComboBox *combobox = new QComboBox(parent);
|
||||
for (int index = 0; index < s_device_gain_list.size(); ++index) {
|
||||
QString value = s_device_gain_list.at(index);
|
||||
combobox->addItem(value, index + 1);
|
||||
}
|
||||
editor = combobox;
|
||||
} break;
|
||||
case 3: { // 软件增益
|
||||
case 4: { // 软件增益
|
||||
QSpinBox* spinbox = new QSpinBox(parent);
|
||||
spinbox->setRange(1, 2^32-1);
|
||||
editor = spinbox;
|
||||
} break;
|
||||
case 4: { // 时间常数
|
||||
QSpinBox* spinbox = new QSpinBox(parent);
|
||||
case 5: { // 时间常数
|
||||
QDoubleSpinBox* spinbox = new QDoubleSpinBox(parent);
|
||||
spinbox->setRange(1, 100);
|
||||
editor = spinbox;
|
||||
} break;
|
||||
case 5: { // 直流偏移
|
||||
case 6: { // 直流偏移
|
||||
QSpinBox* spinbox = new QSpinBox(parent);
|
||||
spinbox->setRange(-1000, 1000);
|
||||
editor = spinbox;
|
||||
} break;
|
||||
case 6: { // 上升时间
|
||||
case 7: { // 成形时间
|
||||
QSpinBox* spinbox = new QSpinBox(parent);
|
||||
spinbox->setRange(1, 255);
|
||||
spinbox->setRange(1, 10);
|
||||
editor = spinbox;
|
||||
} break;
|
||||
case 7: { // 平顶时间
|
||||
QSpinBox* spinbox = new QSpinBox(parent);
|
||||
spinbox->setRange(1, 255);
|
||||
case 8: { // 快通道触发阈值
|
||||
QDoubleSpinBox* spinbox = new QDoubleSpinBox(parent);
|
||||
spinbox->setRange(0, 1000);
|
||||
editor = spinbox;
|
||||
} break;
|
||||
case 8: { // 最大能量范围
|
||||
QSpinBox* spinbox = new QSpinBox(parent);
|
||||
spinbox->setRange(0, 99999);
|
||||
editor = spinbox;
|
||||
case 9: { // CR微分模式
|
||||
QComboBox *combobox = new QComboBox(parent);
|
||||
combobox->addItem(QStringLiteral(u"启用"), true);
|
||||
combobox->addItem(QStringLiteral(u"禁用"), false);
|
||||
editor = combobox;
|
||||
} break;
|
||||
case 10: { // 输入信号正负极性选择
|
||||
QComboBox *combobox = new QComboBox(parent);
|
||||
combobox->addItem(QStringLiteral(u"启用"), true);
|
||||
combobox->addItem(QStringLiteral(u"禁用"), false);
|
||||
editor = combobox;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -80,24 +105,47 @@ void DeviceParamsItemDelegate::setEditorData(QWidget* editor, const QModelIndex&
|
|||
int col = index.column();
|
||||
switch (col) {
|
||||
case 1:
|
||||
case 2: {
|
||||
case 2:
|
||||
case 3: {
|
||||
QComboBox *combo = qobject_cast<QComboBox*>(editor);
|
||||
if (combo) {
|
||||
int idx = combo->findText(value.toString());
|
||||
if (idx >= 0) combo->setCurrentIndex(idx);
|
||||
}
|
||||
} break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8: {
|
||||
case 4: {
|
||||
QSpinBox *spinbox = qobject_cast<QSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
spinbox->setValue(value.toUInt());
|
||||
}
|
||||
} break;
|
||||
case 5: {
|
||||
QDoubleSpinBox *spinbox = qobject_cast<QDoubleSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
spinbox->setValue(value.toDouble());
|
||||
}
|
||||
} break;
|
||||
case 6:
|
||||
case 7: {
|
||||
QSpinBox *spinbox = qobject_cast<QSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
spinbox->setValue(value.toUInt());
|
||||
}
|
||||
} break;
|
||||
case 8: {
|
||||
QDoubleSpinBox *spinbox = qobject_cast<QDoubleSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
spinbox->setValue(value.toDouble());
|
||||
}
|
||||
} break;
|
||||
case 9:
|
||||
case 10: {
|
||||
QComboBox *combo = qobject_cast<QComboBox*>(editor);
|
||||
if (combo) {
|
||||
int idx = combo->findText(value.toString());
|
||||
if (idx >= 0) combo->setCurrentIndex(idx);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -108,23 +156,45 @@ void DeviceParamsItemDelegate::setModelData(QWidget* editor, QAbstractItemModel*
|
|||
int col = index.column();
|
||||
switch (col) {
|
||||
case 1:
|
||||
case 2: {
|
||||
case 2:
|
||||
case 3: {
|
||||
QComboBox *combobox = qobject_cast<QComboBox*>(editor);
|
||||
if (combobox) {
|
||||
model->setData(index, combobox->currentText());
|
||||
}
|
||||
} break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8: {
|
||||
case 4: {
|
||||
QSpinBox *spinbox = qobject_cast<QSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
model->setData(index, spinbox->value());
|
||||
}
|
||||
} break;
|
||||
case 5: {
|
||||
QDoubleSpinBox *spinbox = qobject_cast<QDoubleSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
model->setData(index, spinbox->value());
|
||||
}
|
||||
} break;
|
||||
case 6:
|
||||
case 7: {
|
||||
QSpinBox *spinbox = qobject_cast<QSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
model->setData(index, spinbox->value());
|
||||
}
|
||||
} break;
|
||||
case 8: {
|
||||
QDoubleSpinBox *spinbox = qobject_cast<QDoubleSpinBox*>(editor);
|
||||
if (spinbox) {
|
||||
model->setData(index, spinbox->value());
|
||||
}
|
||||
} break;
|
||||
case 9:
|
||||
case 10: {
|
||||
QComboBox *combobox = qobject_cast<QComboBox*>(editor);
|
||||
if (combobox) {
|
||||
model->setData(index, combobox->currentText());
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -171,6 +241,7 @@ DeviceParamsTableForm::DeviceParamsTableForm(QWidget* parent)
|
|||
ui->params_cfg_table->setItem(row, 7, new QTableWidgetItem());
|
||||
ui->params_cfg_table->setItem(row, 8, new QTableWidgetItem());
|
||||
ui->params_cfg_table->setItem(row, 9, new QTableWidgetItem());
|
||||
ui->params_cfg_table->setItem(row, 10, new QTableWidgetItem());
|
||||
}
|
||||
|
||||
connect(ui->btn_all_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onAllSelectBtnClicked);
|
||||
|
|
@ -178,6 +249,7 @@ DeviceParamsTableForm::DeviceParamsTableForm(QWidget* parent)
|
|||
connect(ui->btn_channel_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onCfgChannelSelectBtnClicked);
|
||||
connect(ui->btn_update_to_other, &QPushButton::clicked, this, &DeviceParamsTableForm::onCurrentChannelToOther);
|
||||
connect(ui->btn_save, &QPushButton::clicked, this, &DeviceParamsTableForm::onSaveSelectedChannelConfig);
|
||||
connect(ui->btn_save_to_sys, &QPushButton::clicked, this, &DeviceParamsTableForm::onSaveSelectedChannelConfigToSys);
|
||||
}
|
||||
|
||||
DeviceParamsTableForm::~DeviceParamsTableForm()
|
||||
|
|
@ -204,6 +276,18 @@ void DeviceParamsTableForm::SetConfigFilename(const QString& filename)
|
|||
if (!json_doc.isObject())
|
||||
return;
|
||||
QVariantMap device_config_info = json_doc.object().toVariantMap();
|
||||
if (device_config_info.contains(QStringLiteral(u"ParamsConfigureInfo"))) {
|
||||
QVariantMap config_info = device_config_info[QStringLiteral(u"ParamsConfigureInfo")].toMap();
|
||||
if (config_info.contains(QStringLiteral(u"Name"))) {
|
||||
this->_cfg_name = config_info[QStringLiteral(u"Name")].toString();
|
||||
}
|
||||
if (config_info.contains(QStringLiteral(u"Description"))) {
|
||||
this->_cfg_description = config_info[QStringLiteral(u"Description")].toString();
|
||||
}
|
||||
}
|
||||
|
||||
this->ClearParamsTable();
|
||||
|
||||
if (!device_config_info.contains(QStringLiteral(u"ChannelConfig")))
|
||||
return;
|
||||
QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList();
|
||||
|
|
@ -220,31 +304,57 @@ void DeviceParamsTableForm::SetConfigFilename(const QString& filename)
|
|||
int row = board_id * 4 + channel_id;
|
||||
if (row >= 32)
|
||||
continue;
|
||||
QVariantMap channel_info;
|
||||
channel_info["board_id"] = board_id;
|
||||
channel_info["channel_id"] = channel_id;
|
||||
ui->params_cfg_table->item(row, 0)->setData(Qt::UserRole, channel_info);
|
||||
// QVariantMap channel_info;
|
||||
// channel_info["board_id"] = board_id;
|
||||
// channel_info["channel_id"] = channel_id;
|
||||
// ui->params_cfg_table->item(row, 0)->setData(Qt::UserRole, channel_info);
|
||||
if (channel_config_info.contains("AddrCount"))
|
||||
ui->params_cfg_table->item(row, 1)->setText(channel_config_info["AddrCount"].toString());
|
||||
if (channel_config_info.contains("TransferMode")) {
|
||||
int transfer_mode = channel_config_info["TransferMode"].toInt();
|
||||
ui->params_cfg_table->item(row, 2)->setText(s_transfer_mode_list.value(transfer_mode));
|
||||
}
|
||||
if (channel_config_info.contains("DeviceGain"))
|
||||
ui->params_cfg_table->item(row, 2)->setText(channel_config_info["DeviceGain"].toString());
|
||||
if (channel_config_info.contains("DeviceGainSelectIndex"))
|
||||
ui->params_cfg_table->item(row, 2)->setData(Qt::UserRole, channel_config_info["DeviceGainSelectIndex"]);
|
||||
ui->params_cfg_table->item(row, 3)->setText(channel_config_info["DeviceGain"].toString());
|
||||
// if (channel_config_info.contains("DeviceGainSelectIndex"))
|
||||
// ui->params_cfg_table->item(row, 3)->setData(Qt::UserRole, channel_config_info["DeviceGainSelectIndex"]);
|
||||
if (channel_config_info.contains("SoftGain"))
|
||||
ui->params_cfg_table->item(row, 3)->setText(channel_config_info["SoftGain"].toString());
|
||||
ui->params_cfg_table->item(row, 4)->setText(channel_config_info["SoftGain"].toString());
|
||||
if (channel_config_info.contains("TimeConst"))
|
||||
ui->params_cfg_table->item(row, 4)->setText(channel_config_info["TimeConst"].toString());
|
||||
ui->params_cfg_table->item(row, 5)->setText(channel_config_info["TimeConst"].toString());
|
||||
if (channel_config_info.contains("DcOffset"))
|
||||
ui->params_cfg_table->item(row, 5)->setText(channel_config_info["DcOffset"].toString());
|
||||
if (channel_config_info.contains("RiseTime"))
|
||||
ui->params_cfg_table->item(row, 6)->setText(channel_config_info["RiseTime"].toString());
|
||||
if (channel_config_info.contains("FlatTime"))
|
||||
ui->params_cfg_table->item(row, 7)->setText(channel_config_info["FlatTime"].toString());
|
||||
if (channel_config_info.contains("MaxEnergy"))
|
||||
ui->params_cfg_table->item(row, 8)->setText(channel_config_info["MaxEnergy"].toString());
|
||||
ui->params_cfg_table->item(row, 6)->setText(channel_config_info["DcOffset"].toString());
|
||||
if (channel_config_info.contains("FormTime"))
|
||||
ui->params_cfg_table->item(row, 7)->setText(channel_config_info["FormTime"].toString());
|
||||
if (channel_config_info.contains("FastChannelTrigerValue"))
|
||||
ui->params_cfg_table->item(row, 8)->setText(channel_config_info["FastChannelTrigerValue"].toString());
|
||||
if (channel_config_info.contains("CRDivMode")) {
|
||||
bool CRDiv_mode = channel_config_info["CRDivMode"].toBool();
|
||||
ui->params_cfg_table->item(row, 9)->setText(CRDiv_mode ? QStringLiteral(u"启用") : QStringLiteral(u"禁用"));
|
||||
}
|
||||
if (channel_config_info.contains("InputSignalPostive")) {
|
||||
bool input_signal_postive = channel_config_info["InputSignalPostive"].toBool();
|
||||
ui->params_cfg_table->item(row, 10)->setText(input_signal_postive ? QStringLiteral(u"启用") : QStringLiteral(u"禁用"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParamsTableForm::SetButtonEnable(bool enable)
|
||||
{
|
||||
ui->btn_save->setVisible(enable);
|
||||
ui->btn_save_to_sys->setVisible(enable);
|
||||
}
|
||||
|
||||
const QString &DeviceParamsTableForm::GetConfigName() const
|
||||
{
|
||||
return _cfg_name;
|
||||
}
|
||||
|
||||
const QString &DeviceParamsTableForm::GetConfigDescription() const
|
||||
{
|
||||
return _cfg_description;
|
||||
}
|
||||
|
||||
void DeviceParamsTableForm::onAllSelectBtnClicked()
|
||||
{
|
||||
for (int row = 0; row < 32; ++row) {
|
||||
|
|
@ -322,14 +432,57 @@ void DeviceParamsTableForm::onCurrentChannelToOther()
|
|||
for (int row = 0; row < 32; ++row) {
|
||||
if (ui->params_cfg_table->isRowHidden(row))
|
||||
continue;
|
||||
for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) {
|
||||
const QString& current_value = ui->params_cfg_table->item(current_row, col)->text();
|
||||
ui->params_cfg_table->item(row, col)->setText(current_value);
|
||||
if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) {
|
||||
for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) {
|
||||
QTableWidgetItem* current_item = ui->params_cfg_table->item(current_row, col);
|
||||
if (current_item) {
|
||||
const QString& current_value = current_item->text();
|
||||
ui->params_cfg_table->item(row, col)->setText(current_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParamsTableForm::onSaveSelectedChannelConfig()
|
||||
{
|
||||
if (SaveSelectedChannelConfig(this->_config_filename, this->_cfg_name, this->_cfg_description)) {
|
||||
emit deviceConfigParamsSaved(this->_config_filename);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParamsTableForm::onSaveSelectedChannelConfigToSys()
|
||||
{
|
||||
int selected_channel_count = 0;
|
||||
for (int row = 0; row < 32; ++row) {
|
||||
if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) {
|
||||
++selected_channel_count;
|
||||
}
|
||||
}
|
||||
if (0 == selected_channel_count) {
|
||||
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!"));
|
||||
return;
|
||||
}
|
||||
DeviceParamsSaveToSysDlg params_save_to_sys_dlg;
|
||||
if (QDialog::Accepted == params_save_to_sys_dlg.exec()) {
|
||||
const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams");
|
||||
const QString params_cfg_name = params_save_to_sys_dlg.GetCfgName();
|
||||
const QString params_cfg_description = params_save_to_sys_dlg.GetCfgDescription();
|
||||
const QString params_cfg_filename = QDir(device_params_dir_path).filePath(params_cfg_name) + ".mscfg";
|
||||
if (QFile::exists(params_cfg_filename)) {
|
||||
QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"设备测量参数配置\"%1\"已存在!").arg(params_cfg_name));
|
||||
} else {
|
||||
if (this->SaveSelectedChannelConfig(params_cfg_filename, params_cfg_name, params_cfg_description)) {
|
||||
this->_cfg_name = params_cfg_name;
|
||||
this->_cfg_description = params_cfg_description;
|
||||
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"保存设备测量参数配置\"%1\"完成").arg(params_cfg_name));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceParamsTableForm::SaveSelectedChannelConfig(const QString &save_filename, const QString& cfg_name, const QString& description)
|
||||
{
|
||||
QVariantList device_channel_params_list;
|
||||
for (int row = 0; row < 32; ++row) {
|
||||
|
|
@ -338,44 +491,82 @@ void DeviceParamsTableForm::onSaveSelectedChannelConfig()
|
|||
int board_id = channel_info["board_id"].toInt();
|
||||
int channel_id = channel_info["channel_id"].toInt();
|
||||
int addr_count = ui->params_cfg_table->item(row, 1)->text().toInt();
|
||||
int device_gain = ui->params_cfg_table->item(row, 2)->text().toInt();
|
||||
int device_gain_index = ui->params_cfg_table->item(row, 2)->data(Qt::UserRole).toInt();
|
||||
uint soft_gain = ui->params_cfg_table->item(row, 3)->text().toUInt();
|
||||
int time_const = ui->params_cfg_table->item(row, 4)->text().toInt();
|
||||
int dc_offset = ui->params_cfg_table->item(row, 5)->text().toInt();
|
||||
int rise_time = ui->params_cfg_table->item(row, 6)->text().toInt();
|
||||
int flat_time = ui->params_cfg_table->item(row, 7)->text().toInt();
|
||||
int max_energy = ui->params_cfg_table->item(row, 8)->text().toInt();
|
||||
|
||||
auto transfer_mode_value = [](const QString& transfer_mode_text) {
|
||||
int transfer_mode = 3;
|
||||
for (QMap<int, QString>::iterator it = s_transfer_mode_list.begin(); it != s_transfer_mode_list.end(); ++it) {
|
||||
if (it.value() == transfer_mode_text) {
|
||||
transfer_mode = it.key();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return transfer_mode;
|
||||
};
|
||||
int transfer_mode = transfer_mode_value(ui->params_cfg_table->item(row, 2)->text());
|
||||
int device_gain = ui->params_cfg_table->item(row, 3)->text().toInt();
|
||||
int device_gain_index = s_device_gain_list.indexOf(ui->params_cfg_table->item(row, 3)->text()) + 1;
|
||||
uint soft_gain = ui->params_cfg_table->item(row, 4)->text().toUInt();
|
||||
double time_const = ui->params_cfg_table->item(row, 5)->text().toDouble();
|
||||
int dc_offset = ui->params_cfg_table->item(row, 6)->text().toInt();
|
||||
int form_time = ui->params_cfg_table->item(row, 7)->text().toInt();
|
||||
double fast_channel_triger_value = ui->params_cfg_table->item(row, 8)->text().toDouble();
|
||||
|
||||
auto is_enable = [](const QString& text) {
|
||||
bool enable = false;
|
||||
if (QStringLiteral(u"启用") == text) {
|
||||
enable = true;
|
||||
} else if (QStringLiteral(u"禁用") == text) {
|
||||
enable = false;
|
||||
}
|
||||
return enable;
|
||||
};
|
||||
bool CRDiv_mode = is_enable(ui->params_cfg_table->item(row, 9)->text());
|
||||
bool input_signal_postive = is_enable(ui->params_cfg_table->item(row, 10)->text());
|
||||
|
||||
QVariantMap device_channel_params;
|
||||
device_channel_params["BoardId"] = board_id;
|
||||
device_channel_params["ChannelId"] = channel_id;
|
||||
device_channel_params["AddrCount"] = addr_count;
|
||||
device_channel_params["TransferMode"] = transfer_mode;
|
||||
device_channel_params["DeviceGain"] = device_gain;
|
||||
device_channel_params["DeviceGainSelectIndex"] = device_gain_index;
|
||||
device_channel_params["SoftGain"] = soft_gain;
|
||||
device_channel_params["TimeConst"] = time_const;
|
||||
device_channel_params["DcOffset"] = dc_offset;
|
||||
device_channel_params["RiseTime"] = rise_time;
|
||||
device_channel_params["FlatTime"] = flat_time;
|
||||
device_channel_params["MaxEnergy"] = max_energy;
|
||||
device_channel_params["FormTime"] = form_time;
|
||||
device_channel_params["FastChannelTrigerValue"] = fast_channel_triger_value;
|
||||
device_channel_params["CRDivMode"] = CRDiv_mode;
|
||||
device_channel_params["InputSignalPostive"] = input_signal_postive;
|
||||
device_channel_params_list.append(device_channel_params);
|
||||
}
|
||||
}
|
||||
if (device_channel_params_list.isEmpty()) {
|
||||
QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!"));
|
||||
return;
|
||||
}
|
||||
// if (device_channel_params_list.isEmpty()) {
|
||||
// QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!"));
|
||||
// return false;
|
||||
// }
|
||||
QVariantMap device_config_info;
|
||||
if (!cfg_name.isEmpty()) {
|
||||
QVariantMap cfg_info;
|
||||
cfg_info["Name"] = cfg_name;
|
||||
cfg_info["Description"] = description;
|
||||
device_config_info["ParamsConfigureInfo"] = cfg_info;
|
||||
}
|
||||
device_config_info["ChannelConfig"] = device_channel_params_list;
|
||||
QJsonDocument json_doc = QJsonDocument::fromVariant(device_config_info);
|
||||
QFile json_file(this->_config_filename);
|
||||
QFile json_file(save_filename);
|
||||
if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
json_file.write(json_doc.toJson());
|
||||
json_file.close();
|
||||
LOG_INFO(QStringLiteral(u"测量设备参数配置保存完成."));
|
||||
|
||||
emit deviceConfigParamsSaved(this->_config_filename);
|
||||
LOG_INFO(QStringLiteral(u"测量设备参数配置保存完成: %1.").arg(save_filename));
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceParamsTableForm::ClearParamsTable()
|
||||
{
|
||||
for (int row = 0; row < ui->params_cfg_table->rowCount(); ++row) {
|
||||
for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) {
|
||||
ui->params_cfg_table->item(row, col)->setText(QString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@ public:
|
|||
explicit DeviceParamsItemDelegate(QObject *parent = nullptr);
|
||||
|
||||
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
||||
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
protected:
|
||||
|
|
@ -36,12 +33,20 @@ public:
|
|||
|
||||
void SetConfigFilename(const QString& filename);
|
||||
|
||||
void SetButtonEnable(bool enable = true);
|
||||
const QString& GetConfigName() const;
|
||||
const QString& GetConfigDescription() const;
|
||||
|
||||
void ClearParamsTable();
|
||||
bool SaveSelectedChannelConfig(const QString& save_filename, const QString &cfg_name = QString(), const QString &description = QString());
|
||||
|
||||
private slots:
|
||||
void onAllSelectBtnClicked();
|
||||
void onReserveSelectBtnClicked();
|
||||
void onCfgChannelSelectBtnClicked();
|
||||
void onCurrentChannelToOther();
|
||||
void onSaveSelectedChannelConfig();
|
||||
void onSaveSelectedChannelConfigToSys();
|
||||
|
||||
signals:
|
||||
void deviceConfigParamsSaved(const QString& filename);
|
||||
|
|
@ -49,6 +54,8 @@ signals:
|
|||
private:
|
||||
Ui::DeviceParamsTableForm *ui;
|
||||
QString _config_filename;
|
||||
QString _cfg_name;
|
||||
QString _cfg_description;
|
||||
};
|
||||
|
||||
#endif // DEVICEPARAMSTABLEFORM_H
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="btn_update_to_other">
|
||||
<property name="text">
|
||||
<string>应用当前通道配置到其他通道</string>
|
||||
<string>应用当前通道配置到选择通道</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -68,6 +68,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_save_to_sys">
|
||||
<property name="text">
|
||||
<string>保存到系统</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
|
@ -113,16 +120,6 @@
|
|||
<string>直流偏移</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>上升时间</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>平顶时间</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>成形时间</string>
|
||||
|
|
@ -138,16 +135,6 @@
|
|||
<string>CR微分模式</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>新建列</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>新建列</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>输入信号正负极性选择</string>
|
||||
|
|
|
|||
18
src/main.cpp
18
src/main.cpp
|
|
@ -7,6 +7,17 @@
|
|||
#include "QsLogManage.h"
|
||||
#include <QThreadPool>
|
||||
|
||||
void InitAppRunEnv() {
|
||||
// 在应用程序可执行文件所在目录检查并创建Projects目录
|
||||
QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects");
|
||||
QDir projects_dir(projects_dir_path);
|
||||
projects_dir.mkpath(projects_dir_path);
|
||||
|
||||
QString device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams");
|
||||
QDir device_params_dir(device_params_dir_path);
|
||||
device_params_dir.mkpath(device_params_dir_path);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
qputenv("QT_WIN_DEBUG_CONSOLE", "attach");
|
||||
|
|
@ -53,12 +64,7 @@ int main(int argc, char *argv[])
|
|||
app.setWindowIcon(QIcon(":/logo/256.png"));
|
||||
app.setQuitOnLastWindowClosed(true);
|
||||
|
||||
// 在应用程序可执行文件所在目录检查并创建Projects目录
|
||||
QString projects_dir_path = QDir(app.applicationDirPath()).filePath("Projects");
|
||||
QDir projects_dir(projects_dir_path);
|
||||
if (!projects_dir.exists()) {
|
||||
projects_dir.mkpath(projects_dir_path);
|
||||
}
|
||||
InitAppRunEnv();
|
||||
|
||||
MainWindow w;
|
||||
w.showMaximized();
|
||||
|
|
|
|||
17
src/src.pro
17
src/src.pro
|
|
@ -70,9 +70,6 @@ SOURCES += \
|
|||
CountRateAnalysisView/CountRateAnalysisView.cpp \
|
||||
CustomQwtPlot.cpp \
|
||||
DataProcessWorkPool.cpp \
|
||||
DeviceParameterConfig/DeviceConfigView.cpp \
|
||||
DeviceParameterConfig/DeviceParameterConfig.cpp \
|
||||
DeviceParameterConfig/DeviceParameterConfigList.cpp \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \
|
||||
EnergyCountPeakFitView/PeakFitParamsDialog.cpp \
|
||||
EnergyCountPeakFitView/PlotRectItem.cpp \
|
||||
|
|
@ -82,6 +79,8 @@ SOURCES += \
|
|||
MainWindow.cpp \
|
||||
MeasureAnalysisDataTableView/MeasureAnalysisDataTableView.cpp \
|
||||
MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.cpp \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.cpp \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.cpp \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsTableForm.cpp \
|
||||
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.cpp \
|
||||
NuclideLib/sqlitemanager.cpp \
|
||||
|
|
@ -90,7 +89,6 @@ SOURCES += \
|
|||
ParticleCountPlotView/ParticleCountPlotView.cpp \
|
||||
MeasureAnalysisTreeView.cpp \
|
||||
MeasureAnalysisView.cpp \
|
||||
MeasureDeviceParamsCfgForm.cpp \
|
||||
NewMeasureAnalysisDlg.cpp \
|
||||
MeasureAnalysisProjectModel.cpp \
|
||||
ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp \
|
||||
|
|
@ -104,7 +102,6 @@ SOURCES += \
|
|||
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.cpp \
|
||||
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \
|
||||
DeviceParameterConfig/DeviceParameterProxy.cpp \
|
||||
ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp \
|
||||
NuclideLib/NuclideLib.cpp \
|
||||
main.cpp
|
||||
|
|
@ -117,9 +114,6 @@ HEADERS += \
|
|||
CountRateAnalysisView/CountRateAnalysisView.h \
|
||||
CustomQwtPlot.h \
|
||||
DataProcessWorkPool.h \
|
||||
DeviceParameterConfig/DeviceConfigView.h \
|
||||
DeviceParameterConfig/DeviceParameterConfig.h \
|
||||
DeviceParameterConfig/DeviceParameterConfigList.h \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.h \
|
||||
EnergyCountPeakFitView/PeakFitParamsDialog.h \
|
||||
EnergyCountPeakFitView/PlotRectItem.h \
|
||||
|
|
@ -130,6 +124,8 @@ HEADERS += \
|
|||
MainWindow.h \
|
||||
MeasureAnalysisDataTableView/MeasureAnalysisDataTableView.h \
|
||||
MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.h \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.h \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.h \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsTableForm.h \
|
||||
MeasureDeviceParamsConfigView/MeasureDeviceParamsConfigView.h \
|
||||
NuclideLib/sqlitemanager.h \
|
||||
|
|
@ -138,7 +134,6 @@ HEADERS += \
|
|||
ParticleCountPlotView/ParticleCountPlotView.h \
|
||||
MeasureAnalysisTreeView.h \
|
||||
MeasureAnalysisView.h \
|
||||
MeasureDeviceParamsCfgForm.h \
|
||||
NewMeasureAnalysisDlg.h \
|
||||
MeasureAnalysisProjectModel.h \
|
||||
ParticleInjectTimeView/ParticleInjectTimeAnalysisView.h \
|
||||
|
|
@ -153,7 +148,6 @@ HEADERS += \
|
|||
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.h \
|
||||
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.h \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.h \
|
||||
DeviceParameterConfig/DeviceParameterProxy.h \
|
||||
ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h \
|
||||
NuclideLib/NuclideLib.h
|
||||
|
||||
|
|
@ -167,9 +161,10 @@ FORMS += \
|
|||
EnergyScaleForm.ui \
|
||||
MainWindow.ui \
|
||||
MeasureAnalysisHistoryForm/MeasureAnalysisHistoryForm.ui \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsManagerDlg.ui \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsSaveToSysDlg.ui \
|
||||
MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui \
|
||||
ParticleCountPlotView/BatchEnergyScaleDialog.ui \
|
||||
MeasureDeviceParamsCfgForm.ui \
|
||||
NewMeasureAnalysisDlg.ui \
|
||||
ThreeDimensionalConformityAnalysisView/DetectorStatusSummary.ui \
|
||||
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.ui \
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ QHeaderView::section {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
QScrollBar {
|
||||
background-color: #f6f5ec;
|
||||
padding: 0px;
|
||||
|
|
@ -90,5 +90,5 @@ QScrollBar::add-page {
|
|||
QScrollBar::sub-page {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user