72 lines
2.0 KiB
C++
72 lines
2.0 KiB
C++
#ifndef SPINBOX_PASTE_HELPER_H
|
||
#define SPINBOX_PASTE_HELPER_H
|
||
|
||
#include <QObject>
|
||
#include <QEvent>
|
||
#include <QKeyEvent>
|
||
#include <QApplication>
|
||
#include <QClipboard>
|
||
#include <QSpinBox>
|
||
#include <QDoubleSpinBox>
|
||
#include <QAbstractSpinBox>
|
||
|
||
/**
|
||
* @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<QKeyEvent*>(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<QDoubleSpinBox*>(obj)) {
|
||
double val = clipText.toDouble(&ok);
|
||
if (ok) {
|
||
dsb->setValue(val);
|
||
return true;
|
||
}
|
||
} else if (QSpinBox* sb = qobject_cast<QSpinBox*>(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<QAbstractSpinBox*>()) {
|
||
sb->installEventFilter(filter);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif // SPINBOX_PASTE_HELPER_H
|