我有一个将无头使用的RaspberryPi 3,我正在使用https://github.com/adafruit/Adafruit_DotStar_Pi来控制LED,这限制了我使用Python 2.这几乎是我设备的唯一输出,而且只有一个key(特别是来自Bluefruit EZ-Key Bluetooth HID Keyboard Controller的'w')是唯一的输入 - 基本上激活或停用灯光。
我希望在检测到按键事件时调用回调函数来更改某些状态,但到目前为止我找到的所有可用方法(即从/dev/input/event0
读取)似乎都是阻塞的。 python-evdev模块看起来很有用,但所有异步选项看起来都是Python 3。
在GPIO python库中(在Python 2中可以正常工作),当引脚改变状态时会有回调函数,所以我想我希望有一个类似的API来检测按键事件。
代码将在systemd进程中运行,似乎从/dev/input/event0
读取更有可能让我获得有用的关键事件而不是stdin
(它似乎没有被连接到检测系统进程中的按键)。
(This question was off-topic为https://raspberrypi.stackexchange.com/ btw)
答案 0 :(得分:1)
输入设备与任何其他文件基本不同。您可以在其上使用select()
和poll()
(等)来测试输入是否可用。那就是:
import select
dev = open('/dev/input/event4')
p = select.poll()
p.register(dev, select.POLLIN)
我可以通过运行检查输入是否可用:
events = p.poll(0)
这将返回一个空列表,或者它将返回一个列表
(file descriptor, event)
元组;无论哪种情况,它都不会阻止。
根据您的代码,您实际上想要这可以阻止a
小;上面调用中的0
实际上是超时(in
毫秒)。
在此文件描述符上收到POLLIN
事件后,我就知道了
我可以read
来自它的一些数据而不会阻塞。一个完整的例子
可能看起来像:
import os
import select
p = select.poll()
dev = open('/dev/input/event4')
p.register(dev, select.POLLIN)
while True:
events = p.poll(500)
if events:
print 'events:', events
data = os.read(dev.fileno(), 1024)
print 'read: %s' % (repr(data))
else:
print 'no events...'
这会在循环中调用poll
,每次最多可以休眠500毫秒
除非有输入,否则它会立即作出反应。
我喜欢select.poll
因为api比较早的select
更容易
打电话,但我注意到了
python-evdev模块包括
example using
select。
仔细看看这个例子,你实际上可以通过一个
InputDevice到poll
,所以我们可以重写上面的内容:
import os
import select
from evdev import InputDevice
p = select.poll()
dev = InputDevice('/dev/input/event4')
p.register(dev, select.POLLIN)
while True:
events = p.poll(500)
if events:
print 'events:', events
data = list(dev.read())
print 'read: %s' % data
在输出上看到类似的东西:
events: [(3, 1)]
read: [InputEvent(1461702764L, 854531L, 4, 4, 458789L), InputEvent(1461702764L, 854531L, 1, 9, 1L), InputEvent(1461702764L, 854531L, 0, 0, 0L)]
请参阅documentation on the select
module for more
details。
希望这足以让你指出正确的方向。