Skip to content

Phase 3: 输入抽象层 -- 设计意图

为什么选择这种方案

CFDesktop 面向嵌入式工控屏、平板和桌面多种形态,输入源差异极大:低端工控屏仅有电阻触摸+GPIO 按键,中端设备带旋转编码器,桌面端则是鼠标键盘。如果不做输入抽象,每个 Widget 必须分别处理 QTouchEvent、QKeyEvent、QWheelEvent 以及原生 evdev/GPIO 事件,导致大量重复代码且难以保证跨设备行为一致。

因此设计了 InputManager 单一分发层:所有输入源(Qt 事件、evdev 设备、GPIO、旋转编码器)先被各自的 Handler 转换为统一的 InputEvent 体系(PointerEvent / KeyEvent / RotaryEvent / GestureEvent),再由 InputManager 统一分发到目标控件。这样 Widget 层只对接一套事件接口,新增输入类型只需添加新的 Handler,不影响上层。

手势识别(GestureRecognizer)从触摸点流中检测 Swipe/Pinch/LongPress/DoubleTap 等手势,将结果作为 GestureEvent 分发。焦点导航(FocusNavigator)为无触摸设备提供基于空间距离的方向导航算法,支持自定义焦点链和循环策略。模拟器通过 SimulatedInputConfig 将鼠标/键盘映射为触摸/旋钮事件,确保开发机和目标设备行为一致。

关键决策

决策理由被否决的替代方案
统一 InputEvent 体系 (PointerEvent/KeyEvent/RotaryEvent/GestureEvent)Widget 只需对接一套接口;新增输入类型只需加 Handler让 Widget 直接处理 Qt 原生事件 + evdev 并行
InputManager 单例 + 事件过滤器链集中管理设备生命周期,支持全局事件拦截(如全局手势)每个 Widget 独立注册输入源
手势识别器独立于 TouchHandler解耦触摸处理与手势判定,可单独禁用/替换手势引擎将手势检测逻辑内嵌在 TouchHandler 中
空间距离焦点导航算法工控屏布局不规则,Tab 顺序不够直观;空间距离更符合用户预期仅使用 Qt Tab 顺序
原生设备层 (evdev/GPIO/RotaryEncoder) 直接读取linuxfb/eglfs 平台下 Qt 不一定转发所有输入;直接读取保证可靠性完全依赖 Qt 平台插件转发
模拟器输入映射 (鼠标->触摸, 滚轮->旋钮)开发机没有触摸/旋钮硬件,映射确保桌面端可调试嵌入式行为要求必须有触摸硬件才能开发

当前状态

未实现。参见 status/current.md Phase 3 部分。

Built with VitePress