#include "DeviceParameterProxy.h" #include #include #include #include #include #include #include #include #include #include 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(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(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(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(editor); if (edit) edit->setText(value.toString()); break; } case 4: // QDoubleSpinBox case 6: { QDoubleSpinBox *spin = qobject_cast(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(editor); if (spin) spin->setValue(value.toInt()); break; } default: { QLineEdit *edit = qobject_cast(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(editor); if (combo) model->setData(index, combo->currentText()); break; } case 3: // 软件增益(字符串存储,因为可能超出int范围) case 8: // 控制功能(字符串存储) case 19: // 总测量时间(字符串存储) { QLineEdit *edit = qobject_cast(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(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(editor); if (spin) model->setData(index, spin->value()); break; } default: { QLineEdit *edit = qobject_cast(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(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(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); }