正在开发一个使用小键盘和电子墨水显示屏的项目,该项目将在 raspberry pi Zero 上运行。我尝试了几个用于 python 的键盘包(pynput、pyxhook),并编写/测试了在我的桌面(ubuntu)上运行良好的简单按键记录器
但是我尝试在没有监视器的情况下在 pi 上运行它们两个库都死了
DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused
我知道至少 pyxhook 能够捕获鼠标移动,因此它“需要”访问监视器的原因是有道理的。但我想要的只是一种在后台运行但未连接监视器的进程中捕获键盘输入的方法
这些库还可以返回当前具有焦点的窗口作为关键事件的一部分,这可能是监视器绑定如此之深的另一个原因。我尝试过
$export DISPLAY=":0"
没有帮助。
这是 pynput 的简单代码,可以与监视器一起使用,但在无头运行时不起作用(从 SSH 运行它)
#!/usr/bin/env python
from pynput import keyboard
def on_press(key):
print('Key {} pressed.'.format(key))
if str(key) == 'Key.esc':
print('Exiting...')
return False
with keyboard.Listener(on_press = on_press) as listener:
listener.join()
有什么方法可以让这些发挥作用,或者可能有不同的方法来解决这个问题。
上述程序失败的完整堆栈跟踪
Traceback (most recent call last):
File "./keylog.py", line 3, in <module>
from pynput import keyboard
File "/usr/local/lib/python2.7/dist-packages/pynput/__init__.py", line 23, in <module>
from . import keyboard
File "/usr/local/lib/python2.7/dist-packages/pynput/keyboard/__init__.py", line 49, in <module>
from ._xorg import KeyCode, Key, Controller, Listener
File "/usr/local/lib/python2.7/dist-packages/pynput/keyboard/_xorg.py", line 38, in <module>
from pynput._util.xorg import (
File "/usr/local/lib/python2.7/dist-packages/pynput/_util/xorg.py", line 38, in <module>
_check()
File "/usr/local/lib/python2.7/dist-packages/pynput/_util/xorg.py", line 36, in _check
display = Xlib.display.Display()
File "/usr/local/lib/python2.7/dist-packages/Xlib/display.py", line 89, in __init__
self.display = _BaseDisplay(display)
File "/usr/local/lib/python2.7/dist-packages/Xlib/display.py", line 71, in __init__
protocol_display.Display.__init__(self, *args, **keys)
File "/usr/local/lib/python2.7/dist-packages/Xlib/protocol/display.py", line 90, in __init__
self.socket = connect.get_socket(name, protocol, host, displayno)
File "/usr/local/lib/python2.7/dist-packages/Xlib/support/connect.py", line 87, in get_socket
return mod.get_socket(dname, protocol, host, dno)
File "/usr/local/lib/python2.7/dist-packages/Xlib/support/unix_connect.py", line 113, in get_socket
raise error.DisplayConnectionError(dname, str(val))
Xlib.error.DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused
答案1
好吧,我想通了,我想我会发布答案。
pythons 键盘模块、文档和源代码这里
如“已知限制”部分所述,(尽管我不认为这是限制!)
“为了避免依赖 X,Linux 部分会读取原始设备文件 (/dev/input/input*),但这需要 root。”
因此,这显然会带来安全问题,因为程序现在需要 root 权限,但就我而言,这不是问题。
pip install keyboard
简单的程序
import keyboard
import time
def key_press(key):
print(key.name)
keyboard.on_press(key_press)
while True:
time.sleep(1)
答案2
我目前正在研究类似的问题。我知道如何解决这个问题。但还没尝试过。不确定我是否应该将其放入一个新问题中。
- 设置自动登录用户的虚拟控制台
- 该控制台不显示交互式 shell (bash),而只是一个监听按键并将其发送到 MPD 的进程
就是这样。您仍然可以使用 Ctrl-Fx 切换到标准控制台,然后正常登录,而不会产生任何副作用,例如不必要的 MPD 控制。
还有几个问题没有解决:
如果没有连接显示器,linux 是否会打开虚拟控制台?
如何设置这个控制台? /etc/login.defs?
侦听器进程使用什么语言和库(到目前为止我用 python 实现了所有内容)
如何将事件传递给 MPD。 (通过 mpc 命令行客户端还是 python mpc 客户端库?)
我将其标记为社区维基。因此,任何人都可以随意为这个答案做出贡献。
背景:我在树莓派上使用 MPD 实现了一个无头音频播放器,目前通过 GPIO 引脚进行控制。现在我也希望能够通过键盘控制它。