EnergySpectrumAnalyer/src/DeviceParameterConfig/DeviceParameterProxy.cpp
2026-03-27 12:55:42 +08:00

385 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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: // 总测量时间__int6464位
{
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);
}