You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下PyQt如何区分USB RFID阅读器与真实键盘的按键事件?

在PyQt中区分RFID虚拟键盘与真实键盘,以及其他数据获取方案(Windows)

一、区分按键事件的来源(真实键盘 vs RFID虚拟键盘)

Qt的QKeyEvent本身不携带设备来源信息,但可以通过调用Windows原生API实现区分:

  • 核心思路:利用Windows的GetMessageExtraInfo()函数获取按键消息的额外信息,其中包含发送消息的HID设备标识;提前获取RFID阅读器的设备ID,在事件触发时对比判断。
  • 具体实现步骤:
    1. 用ctypes调用Windows API,获取当前按键消息对应的设备句柄/ID;
    2. 从设备管理器中查看你的Elatec阅读器的VID/PID(格式为0xXXXX),作为设备唯一标识;
    3. 在PyQt的keyPressEvent中,获取当前设备标识并与阅读器的对比,从而区分来源。

整合后的测试代码:

import sys
import ctypes
from PyQt5.QtWidgets import (QApplication, QWidget)

# Windows API定义
user32 = ctypes.WinDLL('user32', use_last_error=True)
GetMessageExtraInfo = user32.GetMessageExtraInfo
GetMessageExtraInfo.restype = ctypes.LPARAM

# 替换为你的RFID阅读器的VID和PID(从设备管理器获取)
RFID_VID = 0xXXXX
RFID_PID = 0xXXXX

def get_device_vid_pid(handle):
    # 通过设备句柄获取VID/PID,需调用setupapi.dll相关函数
    # 此处为简化示例,实际需补充完整的设备枚举逻辑
    # 可参考Windows SDK中SetupDiGetDeviceRegistryProperty等函数的用法
    return (0, 0)

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

    def keyPressEvent(self, event):
        extra_info = GetMessageExtraInfo()
        # 提取设备句柄(低32位)
        device_handle = ctypes.c_void_p(extra_info & 0xFFFFFFFF)
        vid, pid = get_device_vid_pid(device_handle)
        
        if vid == RFID_VID and pid == RFID_PID:
            print(f"来自RFID阅读器的按键: {event.key()}")
        else:
            print(f"来自真实键盘的按键: {event.key()}")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = MainWindow()
    demo.show()
    sys.exit(app.exec_())

二、其他获取RFID数据的方式

针对Elatec TWN4系列阅读器,除虚拟键盘模式外,还有更可靠的方案:

  • 使用厂商官方SDK:Elatec提供Windows平台的SDK,包含直接与设备通信的API,无需依赖键盘模拟,可直接获取RFID标签的完整数据,还能配置设备工作模式。
  • 切换到HID数据模式:查看设备文档,将阅读器切换为HID数据模式(非键盘模拟),此时设备会以HID报告的形式发送数据,可通过Python的hidapi库直接读取并解析。
  • Raw Input API监听:通过Windows的Raw Input API捕获HID设备的原始输入,绕过键盘模拟层直接获取数据,需处理HID报告的解析逻辑。

HID模式读取示例(使用hidapi)

  1. 安装依赖库:pip install hidapi
  2. 示例代码(替换为你的设备VID/PID):
import hid

# 替换为你的设备VID和PID
VID = 0xXXXX
PID = 0xXXXX

try:
    device = hid.device()
    device.open(VID, PID)
    print("成功连接RFID阅读器")
    
    while True:
        # 读取HID报告,长度参考设备文档调整
        data = device.read(64)
        if data:
            rfid_data = bytes(data).hex()
            print(f"读取到RFID数据: {rfid_data}")
except Exception as e:
    print(f"连接失败: {e}")
finally:
    device.close()

内容的提问来源于stack exchange,提问作者ddhb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:55:17