新增设备参数配置
This commit is contained in:
parent
93225c466e
commit
20d4afc585
446
src/DeviceParameterConfig/DeviceConfigView.cpp
Normal file
446
src/DeviceParameterConfig/DeviceConfigView.cpp
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
#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 <QDebug>
|
||||
|
||||
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 QStandardItemModel(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 = 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);
|
||||
}
|
||||
60
src/DeviceParameterConfig/DeviceConfigView.h
Normal file
60
src/DeviceParameterConfig/DeviceConfigView.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#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);
|
||||
|
||||
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
|
||||
333
src/DeviceParameterConfig/DeviceParameterConfig.cpp
Normal file
333
src/DeviceParameterConfig/DeviceParameterConfig.cpp
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
#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(tr("配置命名:"), this);
|
||||
m_lineEditFileName = new QLineEdit(this);
|
||||
m_btnSave = new QPushButton(tr("保存到测量分析"), this);
|
||||
m_checkBoxSaveToDevice = new QCheckBox(tr("保存到设备参数配置管理"), 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(tr("备注说明:"), 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(tr("设置列"), 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[tr("数据传输模式")] = "eTransferModel";
|
||||
m_columnToJsonKey[tr("硬件增益")] = "iDeviceGain";
|
||||
m_columnToJsonKey[tr("硬件增益选择索引")] = "iDeviceGainSelectIndex";
|
||||
m_columnToJsonKey[tr("软件增益")] = "iSoftGain";
|
||||
m_columnToJsonKey[tr("时间常数")] = "dConstTime";
|
||||
m_columnToJsonKey[tr("成形时间")] = "iFormTime";
|
||||
m_columnToJsonKey[tr("快通道触发阈值")] = "iFastChannelTrigerValue";
|
||||
m_columnToJsonKey[tr("多道分辨率")] = "iChannelNum";
|
||||
m_columnToJsonKey[tr("控制功能")] = "";
|
||||
m_columnToJsonKey[tr("幅度提前延迟")] = "";
|
||||
m_columnToJsonKey[tr("积分长度")] = "";
|
||||
m_columnToJsonKey[tr("dcfd缩放倍数")] = "";
|
||||
m_columnToJsonKey[tr("dcfd延迟")] = "";
|
||||
m_columnToJsonKey[tr("直流偏移")] = "iCurrentOffset";
|
||||
m_columnToJsonKey[tr("最大能量范围")] = "iMaxEnergy";
|
||||
m_columnToJsonKey[tr("Am 峰面积寻峰法的面积比例")] = "iAMPeakDiv";
|
||||
m_columnToJsonKey[tr("K40与 Am241的峰位校正系数")] = "iHVDelt";
|
||||
m_columnToJsonKey[tr("高压关断阈值")] = "iHVDelt";
|
||||
m_columnToJsonKey[tr("获取能谱周期")] = "iGetSpecturmPeirod";
|
||||
m_columnToJsonKey[tr("总测量时间")] = "iTotalMeasureTime";
|
||||
m_columnToJsonKey[tr("总测量次数")] = "iTotalMeasureCount";
|
||||
m_columnToJsonKey[tr("滤波参数")] = "iTrapeTopShitBit";
|
||||
m_columnToJsonKey[tr("上升时间")] = "iRiseTime";
|
||||
m_columnToJsonKey[tr("平顶时间")] = "iTopTime";
|
||||
m_columnToJsonKey[tr("ICR 校正使能")] = "bICRCorrect";
|
||||
m_columnToJsonKey[tr("CRZA 值")] = "iCRZAValue";
|
||||
m_columnToJsonKey[tr("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, tr("错误"), tr("没有选中的配置文件"));
|
||||
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, tr("错误"), tr("无法创建配置文件:%1").arg(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParameterConfig::onSaveButtonClicked()
|
||||
{
|
||||
if (!saveCurrentConfig()) {
|
||||
QMessageBox::warning(this, tr("错误"), tr("保存配置文件失败"));
|
||||
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;
|
||||
}
|
||||
73
src/DeviceParameterConfig/DeviceParameterConfig.h
Normal file
73
src/DeviceParameterConfig/DeviceParameterConfig.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#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
|
||||
214
src/DeviceParameterConfig/DeviceParameterConfigList.cpp
Normal file
214
src/DeviceParameterConfig/DeviceParameterConfigList.cpp
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
#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("设备参数配置列表");
|
||||
mainLayout->addWidget(ListWidgetName);
|
||||
|
||||
m_listWidget = new QListWidget(this);
|
||||
mainLayout->addWidget(m_listWidget);
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout();
|
||||
m_btnAdd = new QPushButton(tr("添加"), this);
|
||||
m_btnDelete = new QPushButton(tr("删除"), 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, tr("新建配置"),
|
||||
tr("请输入配置文件名(无需后缀):"),
|
||||
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, tr("错误"), tr("文件已存在,请使用其他名称。"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 发出创建请求,由外部(主窗口)决定默认内容
|
||||
emit createNewConfigRequested(fileName);
|
||||
}
|
||||
|
||||
void DeviceParameterConfigList::onDeleteClicked()
|
||||
{
|
||||
QListWidgetItem *currentItem = m_listWidget->currentItem();
|
||||
if (!currentItem) {
|
||||
QMessageBox::information(this, tr("提示"), tr("请先选择要删除的配置文件。"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString fileName = currentItem->text();
|
||||
QString filePath = m_folderPath + "/" + fileName;
|
||||
|
||||
int ret = QMessageBox::question(this, tr("确认删除"),
|
||||
tr("确定要删除文件 \"%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, tr("成功"), tr("文件已删除。"));
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("错误"), tr("无法删除文件:%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;
|
||||
}
|
||||
56
src/DeviceParameterConfig/DeviceParameterConfigList.h
Normal file
56
src/DeviceParameterConfig/DeviceParameterConfigList.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#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
|
||||
384
src/DeviceParameterConfig/DeviceParameterProxy.cpp
Normal file
384
src/DeviceParameterConfig/DeviceParameterProxy.cpp
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
#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() << "谱线模式" << "波形模式" << "ADC模式" << "列表模式" << "α/β模式");
|
||||
return combo;
|
||||
}
|
||||
case 1: // 硬件增益(档位)
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << "1" << "2" << "4" << "8" << "16");
|
||||
return combo;
|
||||
}
|
||||
case 2: // 硬件增益选择索引
|
||||
{
|
||||
QComboBox *combo = new QComboBox(parent);
|
||||
combo->addItems(QStringList() << "1" << "2" << "3" << "4" << "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() << "256" << "512" << "1024" << "2048" << "4096" << "8192" << "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() << "关闭" << "启用");
|
||||
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, QString("取值范围: %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, QString("取值范围: %1").arg(rangeHint), edit);
|
||||
return true; // 拦截回车,不提交
|
||||
} else {
|
||||
QToolTip::hideText();
|
||||
// 允许回车提交,Qt 会正常处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::eventFilter(obj, event);
|
||||
}
|
||||
119
src/DeviceParameterConfig/DeviceParameterProxy.h
Normal file
119
src/DeviceParameterConfig/DeviceParameterProxy.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#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
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
#include "MeasureAnalysisView.h"
|
||||
#include "MeasureAnalysisTreeView.h"
|
||||
#include "GlobalDefine.h"
|
||||
|
||||
#include "DeviceParameterConfig.h"
|
||||
using namespace ads;
|
||||
|
||||
MainWindow* MainWindow::_s_main_win = nullptr;
|
||||
|
|
@ -219,7 +219,8 @@ void MainWindow::initAction()
|
|||
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);
|
||||
// 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);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>892</width>
|
||||
<height>22</height>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_measurement_analysis">
|
||||
|
|
|
|||
|
|
@ -64,7 +64,12 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
|||
if (!item)
|
||||
return;
|
||||
if (!_model->GetNodeStatus(item)) {
|
||||
return;
|
||||
QVariant analysis_type_data = _model->GetNodeUserData(item, ProjectList::NodeType);
|
||||
if (!analysis_type_data.isValid())
|
||||
return;
|
||||
AnalysisType analysis_type = analysis_type_data.value<AnalysisType>();
|
||||
if(analysis_type != AnalysisType::DeviceParamsCfg)
|
||||
return;
|
||||
}
|
||||
const QString& item_text = item->text();
|
||||
QVariant project_name_data = _model->GetNodeUserData(item, ProjectList::ProjectName);
|
||||
|
|
@ -232,6 +237,17 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
|||
}
|
||||
}
|
||||
} break;
|
||||
case AnalysisType::DeviceParamsCfg: {
|
||||
MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name);
|
||||
if (project_model) {
|
||||
QString file_name = project_model->GetMeasureDeviceParamsCfgFilename();
|
||||
if (!file_name.isEmpty()) {
|
||||
data_files_set[QStringLiteral(u"设备参数配置")] = file_name;
|
||||
} else {
|
||||
data_files_set[QStringLiteral(u"设备参数配置")] = QString("");
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include "ParticleTimePoorView.h"
|
||||
#include "ConformityAnalysis.h"
|
||||
#include "EnergyCountPeakFitView.h"
|
||||
|
||||
#include "DeviceConfigView.h"
|
||||
MeasureAnalysisView *MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
||||
{
|
||||
MeasureAnalysisView* new_view = nullptr;
|
||||
|
|
@ -18,8 +18,8 @@ MeasureAnalysisView *MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
|||
// new_view->setDeleteOnClose(true);
|
||||
} break;
|
||||
case AnalysisType::DeviceParamsCfg: {
|
||||
// new_view = new MeasureAnalysisDataTableView;
|
||||
// new_view->setDeleteOnClose(true);
|
||||
new_view = new DeviceConfigView;
|
||||
new_view->setDeleteOnClose(true);
|
||||
} break;
|
||||
case AnalysisType::EnergyScale: {
|
||||
// new_view = new MeasureAnalysisDataTableView;
|
||||
|
|
|
|||
19
src/src.pro
19
src/src.pro
|
|
@ -40,7 +40,9 @@ INCLUDEPATH += \
|
|||
$${PWD}/ThreeDimensionalConformityAnalysisView \
|
||||
$${PWD}/EnergyCountPeakFitView \
|
||||
$${PWD}/MeasureAnalysisDataTableView \
|
||||
$${PWD}/MeasureAnalysisHistoryForm
|
||||
$${PWD}/MeasureAnalysisHistoryForm \
|
||||
$${PWD}/DeviceParameterConfig
|
||||
|
||||
|
||||
DEPENDPATH += \
|
||||
$${PWD}/MeasureAnalysisParticleCountPlotView \
|
||||
|
|
@ -52,13 +54,18 @@ DEPENDPATH += \
|
|||
$${PWD}/ThreeDimensionalConformityAnalysisView \
|
||||
$${PWD}/EnergyCountPeakFitView \
|
||||
$${PWD}/MeasureAnalysisDataTableView \
|
||||
$${PWD}/MeasureAnalysisHistoryForm
|
||||
$${PWD}/MeasureAnalysisHistoryForm \
|
||||
$${PWD}/DeviceParameterConfig
|
||||
|
||||
|
||||
SOURCES += \
|
||||
AboutDlg.cpp \
|
||||
CountRateAnalysisView/CountRateAnalysisView.cpp \
|
||||
CustomQwtPlot.cpp \
|
||||
DataProcessWorkPool.cpp \
|
||||
DeviceParameterConfig/DeviceConfigView.cpp \
|
||||
DeviceParameterConfig/DeviceParameterConfig.cpp \
|
||||
DeviceParameterConfig/DeviceParameterConfigList.cpp \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \
|
||||
EnergyCountPlotView/EnergyCountPlotView.cpp \
|
||||
EnergyScaleDataModel.cpp \
|
||||
|
|
@ -85,6 +92,7 @@ SOURCES += \
|
|||
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.cpp \
|
||||
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.cpp \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \
|
||||
DeviceParameterConfig/DeviceParameterProxy.cpp \
|
||||
main.cpp
|
||||
|
||||
HEADERS += \
|
||||
|
|
@ -93,6 +101,9 @@ HEADERS += \
|
|||
CountRateAnalysisView/CountRateAnalysisView.h \
|
||||
CustomQwtPlot.h \
|
||||
DataProcessWorkPool.h \
|
||||
DeviceParameterConfig/DeviceConfigView.h \
|
||||
DeviceParameterConfig/DeviceParameterConfig.h \
|
||||
DeviceParameterConfig/DeviceParameterConfigList.h \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.h \
|
||||
EnergyCountPlotView/EnergyCountPlotView.h \
|
||||
EnergyScaleDataModel.h \
|
||||
|
|
@ -120,7 +131,9 @@ HEADERS += \
|
|||
ThreeDimensionalConformityAnalysisView/DetectorStatusSummary.h \
|
||||
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.h \
|
||||
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.h \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.h
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.h \
|
||||
DeviceParameterConfig/DeviceParameterProxy.h
|
||||
|
||||
|
||||
|
||||
FORMS += \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user