#ifndef SPINBOX_PASTE_HELPER_H #define SPINBOX_PASTE_HELPER_H #include #include #include #include #include #include #include #include /** * @brief SpinBox 粘贴事件过滤器 * QSpinBox/QDoubleSpinBox 带 prefix 时粘贴会被验证器拒绝, * 这里拦截 Ctrl+V,解析剪贴板数值后直接 setValue。 * * 用法:在 setupUI() 之后调用 SpinBoxPasteHelper::install(this); */ class SpinBoxPasteFilter : public QObject { public: explicit SpinBoxPasteFilter(QObject* parent = nullptr) : QObject(parent) {} bool eventFilter(QObject* obj, QEvent* event) override { if (event->type() != QEvent::KeyPress) { return QObject::eventFilter(obj, event); } QKeyEvent* keyEvent = static_cast(event); if (!keyEvent->matches(QKeySequence::Paste)) { return QObject::eventFilter(obj, event); } QString clipText = QApplication::clipboard()->text().trimmed(); bool ok = false; if (QDoubleSpinBox* dsb = qobject_cast(obj)) { double val = clipText.toDouble(&ok); if (ok) { dsb->setValue(val); return true; } } else if (QSpinBox* sb = qobject_cast(obj)) { int val = clipText.toInt(&ok); if (ok) { sb->setValue(val); return true; } } return QObject::eventFilter(obj, event); } }; namespace SpinBoxPasteHelper { /** * @brief 为 parent 下所有 QSpinBox/QDoubleSpinBox 安装粘贴过滤器 */ inline void install(QWidget* parent) { SpinBoxPasteFilter* filter = new SpinBoxPasteFilter(parent); for (QAbstractSpinBox* sb : parent->findChildren()) { sb->installEventFilter(filter); } } } #endif // SPINBOX_PASTE_HELPER_H