Qt应用扫描2D DataMatrix条码时字符丢失问题求助
解决Qt 5.6.3 eglfs环境下GD4500扫描器字符丢失问题
核心问题分析
evtest能输出完整条码,说明Linux驱动层数据正常,问题出在Qt 5.6.3的eglfs键盘事件处理逻辑——快速连续的按键事件被合并或丢弃,且keyboardInputInterval仅支持依赖X11的QApplication,无法在eglfs环境使用。
可行解决思路
1. 直接读取evdev设备(最可靠)
绕开Qt的事件系统,直接从扫描器对应的/dev/input/eventX设备读取原始输入事件,自行解析拼接条码。
实现步骤:
固定扫描器设备路径:通过
evtest找到扫描器对应的event设备,或用udev规则给设备加固定别名(避免重启后event编号变化):
创建/etc/udev/rules.d/99-gd4500-scanner.rules:SUBSYSTEM=="input", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="YYYY", MODE="0666", SYMLINK+="gd4500-scanner"替换
XXXX和YYYY为扫描器的USB厂商/产品ID(可通过lsusb查看)。编写evdev读取线程:用QThread循环读取输入事件,解析键值拼接条码:
#include <QThread> #include <QString> #include <fcntl.h> #include <linux/input.h> #include <unistd.h> class ScannerReader : public QThread { Q_OBJECT protected: void run() override { int fd = open("/dev/gd4500-scanner", O_RDONLY | O_NONBLOCK); if (fd < 0) { qWarning("Failed to open GD4500 scanner device"); return; } struct input_event ev; QString currentBarcode; bool shiftPressed = false; while (!isInterruptionRequested()) { ssize_t n = read(fd, &ev, sizeof(ev)); if (n == sizeof(ev)) { if (ev.type == EV_KEY) { if (ev.value == 1) { // 按键按下 switch(ev.code) { case KEY_LEFTSHIFT: case KEY_RIGHTSHIFT: shiftPressed = true; break; case KEY_ENTER: emit barcodeScanned(currentBarcode); currentBarcode.clear(); break; default: char c = mapKeyCodeToChar(ev.code, shiftPressed); if (c != 0) { currentBarcode.append(c); } break; } } else if (ev.value == 0) { // 按键释放 if (ev.code == KEY_LEFTSHIFT || ev.code == KEY_RIGHTSHIFT) { shiftPressed = false; } } } } usleep(1000); // 降低CPU占用 } close(fd); } char mapKeyCodeToChar(unsigned int code, bool shift) { // 根据键盘布局映射键码到字符,示例仅做基础映射,需补充完整 switch(code) { case KEY_A: return shift ? 'A' : 'a'; case KEY_B: return shift ? 'B' : 'b'; case KEY_0: return shift ? ')' : '0'; case KEY_1: return shift ? '!' : '1'; // 补充其他数字、符号、字母的映射 default: return 0; } } signals: void barcodeScanned(const QString& barcode); };在主程序中使用:启动线程并连接
barcodeScanned信号处理条码数据。
2. 修改Qt EGLFS插件的键盘事件逻辑
Qt 5.6.3的eglfs键盘处理可能存在快速事件丢失的问题,可修改Qt源码调整事件合并策略:
- 找到Qt源码路径:
qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfskerneldevice.cpp - 在键盘事件处理函数中,添加时间间隔判断:记录上一个按键事件的时间戳,当新事件与上一个事件的间隔小于扫描器的输出间隔(比如10ms)时,直接传递事件而不合并。
- 重新编译Qt的eglfs插件,替换原插件。
3. 优化扫描器输出设置
除了调整USB速度,还可通过扫描器的配置条码修改以下参数:
- 增加字符输出间隔:设置为15ms以上,超过Qt事件处理的阈值
- 开启扫描结束标记:确保扫描器输出回车/换行作为条码结束符,方便识别完整条码
- 切换到慢输出模式:部分扫描器支持降低键盘输出速度,适配嵌入式系统的处理能力
4. 升级Qt版本(若项目允许)
Qt 5.6.3是较老的版本,后续LTS版本(如5.12+)修复了大量嵌入式平台的输入事件处理bug,升级后可能直接解决字符丢失问题。
内容的提问来源于stack exchange,提问作者user3172491
相关产品推荐
相关产品推荐

