当前位置: 首页 > news >正文

关于QLineEdit自定义范围

Qt中有很多种情况,比如输入用户名,输入名称等功能,要用到QLineEdit,如果想设置指定的范围,比如说关于名称,常用的可输入配置为,支持中文、英文、数字、特殊符号 - ,长度不超过64字符。在我目前的Qt5.9.6版本中,无法通过简单的正则和方法直接完成。因为关于特殊符号我无论怎么设置都可以输入@ , 。 、 【 】等这些英文和中文的符号,于是我考虑到另一个方法,自定义QLineEdit,重新实现它的KeyPressEvent事件。代码如下

/***************.h文件****************/ #include <QLineEdit> #include <QKeyEvent> class MyLineEdit : public QLineEdit { Q_OBJECT public: explicit MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {} protected: // 重写键盘按下事件 void keyPressEvent(QKeyEvent *event) override; }; /***************.cpp文件****************/ #include "your_header.h" // 包含你的头文件 void MyLineEdit::keyPressEvent(QKeyEvent *event) { // 1. 先放行所有的控制键(比如:退格键删除、Ctrl+C/V、方向键移动光标等) // 如果不放行这些,你的输入框将无法删除内容,也无法使用快捷键 if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete || event->key() == Qt::Key_Left || event->key() == Qt::Key_Right || (event->modifiers() & Qt::ControlModifier)) { QLineEdit::keyPressEvent(event); return; } // 2. 获取当前按下的文本 QString text = event->text(); // 如果文本为空(比如按下了 Shift、Alt 等不产生字符的键),直接放行 if (text.isEmpty()) { QLineEdit::keyPressEvent(event); return; } // 3. 提取第一个字符进行白名单判断 QChar ch = text.at(0); // 白名单规则: // ch.isDigit() -> 数字 (0-9) // ch.isLetter() -> 英文字母 (a-z, A-Z) // (ch >= 0x4e00 && ch <= 0x9fa5) -> 常用中文字符 Unicode 范围 // ch == '-' -> 特殊符号连字符 bool isAllowed = ch.isDigit() || ch.isLetter() || (ch >= 0x4e00 && ch <= 0x9fa5) || ch == '-'; // 4. 如果是允许的字符,就交给 QLineEdit 正常处理;否则直接拦截(不调用父类方法) if (isAllowed) { QLineEdit::keyPressEvent(event); } // 如果不允许(比如输入了 @),这里什么都不做,就相当于把这次按键吞掉了 }

代码完成后,我发现确实英文键盘的情况已经满足我的需求了,特殊符号也仅能输入-了,但是切到中文输入法后,仍然有问题,中文的任意符号是可以输入的,通过打断点发现,在有输入法的时候,qt处理不会进入该事件。

查阅资料后得知,当用输入法打字时,按下键盘,这个事件并没有直接变成字符塞进QLineEdit,而是先被操作系统和Qt的输入法框架(Input Method Framework)给“劫持”了。

完整流程如下

1. 按下键盘-> 产生QKeyEvent(此时进入KeyPressEvent)

2. 输入法拦截了这个事件,把它转换成拼音或候选词(进入了输入法编辑状态)

3. 在输入法里选好了字或符号 (比如选中了一个中文逗号,)

4. 输入法框架会生成一个专门的QInputMethodEvent(输入法事件),直接把最终的字符(,)塞进你的输入框里。

所以,中文符号和汉字是没有经过KeyPressEvent白名单安检,而是走了InputMethodEvent这条通道。

所以我们需要再重写一个InputMethodEvent函数,用和白名单完全一样的逻辑处理输入法提交的字符。

因此在原有类中,加入以下代码

#include <QInputMethodEvent> // 在你的 .h 文件中声明: protected: void inputMethodEvent(QInputMethodEvent *event) override* // 在你的 .cpp 文件中实现: void MyLineEdit::inputMethodEvent(QInputMethodEvent *event) { // 获取输入法最终要提交上屏的文本(比如你选的中文逗号) QString commitText = event->commitString(); // 如果输入法提交了文本,我们就进行拦截检查 if (!commitText.isEmpty()) { // 遍历提交的每一个字符(防止一次性粘贴或输入多个符号) for (QChar ch : commitText) { bool isDigitOrLetter = ch.isDigit() || ch.isLetter(); bool isChineseChar = (ch >= 0x4e00 && ch <= 0x9fa5); bool isHyphen = (ch == '-'); // 拦截全角符号(中文符号) bool isFullWidthSymbol = (ch >= 0xFF00 && ch <= 0xFFEF); // 只要发现有一个字符不符合白名单,或者是全角符号,就直接把整个事件忽略掉 if (!((isDigitOrLetter || isChineseChar || isHyphen) && !isFullWidthSymbol)) { event->ignore(); // 拒绝这次输入法提交 return; } } } // 如果检查通过,或者输入法只是在打出拼音(commitString为空),就正常放行 QLineEdit::inputMethodEvent(event); }

这样,就完成了一个专属于名称输入的控件。

http://www.rkmt.cn/news/1407481.html

相关文章:

  • 14. WDG看门狗
  • 遇到大模型api调用失败时如何利用taotoken控制台进行问题排查
  • GreenSoul框架:基于行为科学与边缘计算的建筑节能物联网实践
  • Modbus通信协议调试实战:以ZLinear数据采集卡为例
  • CANN catlass:FlashAttention 模板的昇腾适配方案
  • Agent系列(六):记忆管理——让 Agent 记住重要的事
  • ASIP架构设计:为深度神经网络定制高效能边缘计算处理器
  • 周二随笔
  • 先进封装GEO优化公司哪家好?2026年半导体封测企业AI获客实战指南 - GEO优化
  • 2026虫草品牌节日礼盒推荐 送礼首选
  • 关于反馈的学习
  • 基于区块链的人机协作数字孪生系统云边协同数据管理研究
  • 2026年 玻璃钢花箱/花盆/花钵厂家推荐榜:IP雕塑与户外家具创意定制实力派深度解析 - 品牌企业推荐师(官方)
  • 埃用仪器|NECPS 2026青岛技术研讨会圆满收官
  • 终极免费QQ音乐格式转换工具QMCDecode:三步解锁加密音频,实现跨设备播放自由
  • 保姆级教程:在Ubuntu 22.04上从零编译WRF4.3和WPS(附依赖库避坑指南)
  • 6G太赫兹MIMO天线设计 + 回归机器学习(ETR)性能预测 —— 附CST/ADS联合仿真与RLC建模
  • 脑启社区上新!三大类脑开发工具同步开源上线
  • 台州路桥汽车音响老店2026亲测 - 资讯纵览
  • 【2024微信生态AI写作白皮书】:基于217篇实测数据,验证ChatGPT提效4.8倍的真实路径
  • 智能体系统设计中的复杂性陷阱与抗脆弱架构实践
  • PostgreSQL逻辑复制全解析:从原理到跨区域实战
  • MyOS第三天——进入32位模式并导入C语言
  • ComfyUI跨系统移植实战:从Windows到Ubuntu 26.04的深度兼容性破解
  • Agent 框架最全解析与实战攻略:LangChain / LangGraph、AutoGen、CrewAI... 到底怎么选?
  • 免费解锁AMD Ryzen隐藏性能:终极硬件调试工具完全指南
  • 天龙八部单机版GM工具终极指南:免费开源的游戏数据管理神器
  • 免费获取macOS风格鼠标指针的终极指南:让你的Windows和Linux桌面焕然一新
  • 2026年三亚汽车贴膜合规资质横向深度测评:4家官方授权门店实测对比 - GrowthUME
  • OpenAI 兼容客户端通用教程:API 地址、密钥与模型名