Python evdev读取设备事件时如何匹配XML内event_cod执行逻辑
问题描述
我有如下xmlfile.xml配置文件,存储输入设备按键码和按键名的映射关系:
<events> <event id="30"> <event_cod>30</event_cod> <event_key>KEY_A</event_key> </event> <event id="23"> <event_cod>23</event_cod> <event_key>KEY_I</event_key> </event> <event id="16"> <event_cod>16</event_cod> <event_key>KEY_Q</event_key> </event> </events>
接入输入设备后,按下按键时设备会返回对应的event.code(取值为30、23、16这类整数),当前编写的Python代码卡在事件码匹配的判断逻辑处,现有代码如下:
device = evdev.InputDevice('/dev/input/eventX') for event in device.read_loop(): if event.value == 1: import xml.etree.ElementTree as ET tree = ET.parse('/xmlfile.xml') for child in tree.getroot(): for core in child: core_value = str(core.text) if event.code == ????????(core_value = 30, 23, 16 etc.): get_xml = ET.parse('/xmlfile.xml') xml_content = get_xml.getroot() print('You Pressed " + xml_content[0][1].text + " Key!')
我是PHP转Python的初学者,需要实现的逻辑:遍历XML内所有配置条目,将设备返回的event.code和XML中存储的<event_cod>节点值做匹配,匹配成功后获取同条目下<event_key>节点的内容,输出按下的按键名。
正确实现方案
先修正现有代码的几个明显问题:
- 模块导入不要写在循环内部,放到代码开头即可
- 不要每次按键都重复解析XML文件,程序启动时一次性加载映射为字典,查询效率更高
- 注意类型匹配:
event.code是整数类型,XML读取的文本是字符串,匹配前要做类型转换 - 不要用固定索引
xml_content[0][1]取按键名,匹配到对应条目后直接读取当前条目的<event_key>值即可 - 读取evdev事件时要加事件类型判断,过滤掉非按键类事件避免误判
推荐写法(性能最优)
程序启动时一次性加载配置,后续按键直接查字典:
import xml.etree.ElementTree as ET import evdev # 启动时加载XML,构建 按键码->按键名 的映射字典 key_map = {} tree = ET.parse('/xmlfile.xml') root = tree.getroot() for event_node in root.findall('event'): code = int(event_node.find('event_cod').text) key_name = event_node.find('event_key').text key_map[code] = key_name # 初始化输入设备 device = evdev.InputDevice('/dev/input/eventX') # 监听按键事件 for event in device.read_loop(): # 仅处理按键按下事件 if event.type == evdev.ecodes.EV_KEY and event.value == 1: if event.code in key_map: print(f'You Pressed {key_map[event.code]} Key!')
遍历匹配写法(不推荐,性能差)
如果要保留每次触发事件时遍历XML的逻辑,匹配写法如下:
import xml.etree.ElementTree as ET import evdev device = evdev.InputDevice('/dev/input/eventX') for event in device.read_loop(): if event.type == evdev.ecodes.EV_KEY and event.value == 1: tree = ET.parse('/xmlfile.xml') root = tree.getroot() pressed_key = None for event_node in root.findall('event'): xml_code = int(event_node.find('event_cod').text) if xml_code == event.code: pressed_key = event_node.find('event_key').text break if pressed_key: print(f'You Pressed {pressed_key} Key!')
内容的提问来源于stack exchange,提问作者adis
相关产品推荐
相关产品推荐

