EnergySpectrumAnalyer/src/DeviceParameterConfig/DeviceParameterProxy.cpp

385 lines
12 KiB
C++
Raw Normal View History

2026-03-27 12:55:42 +08:00
#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);
}