Files
VX5_KRO_GearPump/doc/2026-04-29_BarcodeEditor虚拟键盘不可点击问题修复日志.md
T
2026-04-29 14:10:10 +08:00

122 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-04-29 BarcodeEditor 虚拟键盘不可点击问题修复日志
## 一、问题背景
在 `BarcodeEditor` 中,`lineEditContent` 获取焦点后会正常呼出 `InputMethod` 虚拟键盘,但键盘弹出后,任意按键都无法点击。
用户反馈该问题只出现在 `BarcodeEditor` 场景中,而 `InputMethod` 在系统其他页面表现正常。
## 二、问题现象
- `lineEditContent` 获得焦点后,虚拟键盘可以显示。
- 虚拟键盘显示后,按钮点击无响应。
- 同一套输入法在其他页面可以正常输入,说明不是键盘控件本身整体失效。
## 三、排查思路
本次排查没有只局限在 `BarcodeEditor` 单页,而是沿着“焦点切换 + 全局事件过滤 + 输入法显示/隐藏逻辑”做了整体梳理:
1. 检查 `BarcodeEditor.cpp / .h` 中与编辑框及焦点处理相关的逻辑。
2. 检查 `InputMethod.cpp` 与 `MyInputMethod.cpp` 中虚拟键盘显示、隐藏、发送按键的实现。
3. 检查全局输入法触发入口,最终定位到 `InkJetPrinter::eventFilter(QObject *, QEvent *)`。
排查后确认:
- 当前工程通过 `InkJetPrinter::eventFilter()` 统一处理 `FocusIn / FocusOut`,从而控制虚拟键盘显示与隐藏。
- 若事件处理不区分“点到了输入法自己”还是“点到了其他区域”,就可能出现键盘刚收到点击就被焦点切换或隐藏逻辑打断的问题。
- 因为工程里已经有全局事件过滤,所以比起只在 `BarcodeEditor` 中单点修复,更适合补齐一套通用的“点击空白处失焦并隐藏键盘,同时点击键盘自身不误隐藏”的机制。
## 四、本次修改内容
### 1. 修改 `MyInputMethod.cpp`
新增头文件:
- `#include <QTextEdit>`
新增方法:
#### `bool MyInputMethod::shouldIgnoreHideForWidget(QWidget *widget) const`
作用:
- 判断当前点击/聚焦的控件是否属于虚拟键盘本体;
- 如果是 `inputMethod` 自身、其子控件,或 `digitalInput` 自身、其子控件,则返回 `true`;
- 同时保留对 `inputPreviewBox` 的排除。
这样做的目的,是避免“用户点击虚拟键盘按钮时,程序先把键盘隐藏掉,导致按钮无法真正处理点击”。
#### `void MyInputMethod::clearCurrentFocusAndHide()`
作用:
- 获取当前焦点控件;
- 如果当前焦点不是输入法本体,则清除其焦点;
- 隐藏 `inputMethod` 和 `digitalInput`;
- 调用 `inputMethod->onHiden()` 做隐藏后的清理。
这个方法用于统一处理“点击空白区域时关闭输入法”的需求。
#### 调整 `updateHandler(int type)`
在入口增加:
- 如果当前焦点控件属于输入法自己,则直接返回,不再继续执行隐藏/显示逻辑。
这一步用于避免输入法自身参与焦点切换时,触发错误的隐藏处理。
### 2. 修改 `InkJetPrinter.cpp`
修改 `InkJetPrinter::eventFilter(QObject *watched, QEvent *event)`:
- 保留原有 `FocusIn / FocusOut` 对输入法的显示隐藏控制;
- 新增 `QEvent::MouseButtonPress` 处理。
新增逻辑如下:
- 若当前被点击对象是 `QWidget`;
- 且它不是 `QSpinBox / QLineEdit / QTextEdit` 这类可编辑输入控件;
- 且它也不是虚拟键盘本身及其子控件;
- 则调用 `myInputMethod->clearCurrentFocusAndHide()`。
也就是说:
- 点击输入框:正常保留焦点,键盘继续可用;
- 点击虚拟键盘按钮:不会被误判为“点击空白处”,键盘不会先被隐藏;
- 点击普通空白区域或非编辑控件:输入框失焦,键盘自动收起。
## 五、修复结果
本次修复后,输入法相关行为被整理为一套更稳定的通用机制:
1. 可编辑控件获取焦点时,正常弹出虚拟键盘;
2. 点击虚拟键盘自身时,不会触发误隐藏;
3. 点击页面空白区域或普通控件时,会清理当前焦点并隐藏虚拟键盘。
这次处理不是“只为 `BarcodeEditor` 打补丁”,而是将该问题在全局输入法交互层做了统一修复,可同时改善其他页面的体验一致性。
## 六、验证建议
建议至少验证以下场景:
### `BarcodeEditor`
- 点击 `lineEditContent`,确认虚拟键盘正常弹出;
- 连续点击虚拟键盘字母、数字、退格、确认等按键,确认可以响应;
- 点击页面空白区域,确认输入框失焦且键盘隐藏。
### 其他页面回归验证
- 任意 `QLineEdit` 页面:确认键盘仍可正常呼出和输入;
- `QSpinBox` 页面:确认数字键盘逻辑未受影响;
- `QTextEdit` 页面:确认点击输入法按钮仍可输入文本;
- 点击输入法自身按钮时,不应出现“按下立即消失”或“完全点不动”的现象。
## 七、本次会话记录补充
在本次对话过程中,除修复“`BarcodeEditor` 弹出键盘但无法点击”问题外,还顺带完成了一项通用交互增强:
- **点击空白区域自动失焦并隐藏虚拟键盘**。
该增强已通过全局事件过滤接入,而不是局限于某一个编辑器页面,便于后续维护。