1. 项目背景与需求解析
在开发工业控制上位机软件时,经常需要处理底层硬件设备的寄存器读写操作。这些寄存器地址通常以十六进制形式呈现,偶尔也会遇到二进制或八进制的特殊场景。标准的QTextEdit组件虽然功能强大,但默认支持所有字符输入,无法有效防止用户误输入非指定进制的字符。
最近在开发一个PLC调试工具时,就遇到了这样的需求:需要创建一个只允许输入二进制(0-1)、八进制(0-7)或十六进制(0-9A-Fa-f)的文本输入框。这个需求看似简单,但实现起来需要考虑以下几个关键点:
- 输入过滤:如何实时拦截并过滤非法字符输入
- 进制切换:如何动态切换不同进制模式
- 数据验证:如何保证最终输入的数值有效性
- 用户体验:如何在限制输入的同时保持良好的交互体验
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术方案设计
2.1 基础方案选择
Qt框架本身提供了多种实现输入限制的方式,经过对比分析,我最终选择了基于QTextEdit的派生类方案,主要原因如下:
- 灵活性:相比QLineEdit,QTextEdit支持多行文本,更适合寄存器地址输入场景
- 可扩展性:通过派生类可以完整保留QTextEdit的所有功能,只重写需要修改的部分
- 维护性:独立的类更容易在不同项目中复用
2.2 核心实现思路
实现的核心在于重写以下两个关键方法:
- 键盘事件处理:通过keyPressEvent过滤非法字符输入
- 文本插入控制:通过insertFromMimeData防止粘贴非法内容
同时需要添加进制模式切换功能,允许运行时动态改变允许的字符集。
3. 详细实现步骤
3.1 创建派生类
首先创建一个继承自QTextEdit的类:
cpp复制class NumericTextEdit : public QTextEdit {
Q_OBJECT
public:
enum NumberBase {
Binary = 2,
Octal = 8,
Hexadecimal = 16
};
explicit NumericTextEdit(QWidget *parent = nullptr);
void setNumberBase(NumberBase base);
protected:
void keyPressEvent(QKeyEvent *e) override;
void insertFromMimeData(const QMimeData *source) override;
private:
NumberBase m_base;
QRegularExpression m_validator;
void updateValidator();
};
3.2 实现进制验证逻辑
不同进制下的合法字符规
