2021年07月30日 更新
どうも、クラゲです。
Pythonで実行画面が表示されていなくても、キーボードやマウスなどから入力を受ける方法をご紹介します。応用すれば、無線テンキーボードなどがラズパイのリモコンのように使えて便利です。
Python標準モジュールで使えるinputは以下の課題があります。
上記の1を解決する案として、OpenCVのwaitKey関数やreadcharモジュールなどがありますが、2についてはやはり解決できません。
先程の1と2の両方を解決してくれるのがevdevモジュールです。
https://python-evdev.readthedocs.io
Python3の場合はpip3
でインストールします。
pip3 install evdev
event番号とは具体的には event2
という文字列のことです。
調べる方法はいくつかありますので、お好みでどうぞ。
ラズパイにデバイスを接続した状態で確認してください。デバイスは、マウスやキーボード、テンキーなどを意味しています。
以下のコマンドを打つと詳細情報が出てくるので、何番なのか確認できます。
cat /proc/bus/input/devices
もし、たくさんのデバイスが接続されている場合は、以下のコマンドが便利です。
デバイスを接続する前と後それぞれで、コマンドを打って、差分を見てください。
ls /dev/input
以下のPythonコードでも確認可能です。
この後のサンプルではevent番号で指定していますが、これを活用すればデバイス名で指定することも可能と思います。
import evdev
devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
for device in devices:
print(device.path, device.name, device.phys)
マウスの場合の例です。
左クリック、中央クリック、右クリックを行ったときに表示が出ます。
実行しているプログラムの表示が非アクティブ(他のウィンドウが最前面)であっても読み込まれていると思います。
import evdev
#検知したいデバイスのevent番号を書いてください
device = evdev.InputDevice('/dev/input/event0')
for event in device.read_loop():
if event.type == evdev.ecodes.EV_KEY:
if event.value == 1: #0:UP, 1:DOWN
if event.code == evdev.ecodes.BTN_LEFT:
print('Left Click')
if event.code == evdev.ecodes.BTN_MIDDLE:
print('Middle Click')
if event.code == evdev.ecodes.BTN_RIGHT:
print('Right Click')
テンキーの場合の例です。
1
, 2
, 3
のキーを押すと表示が出ます。
import evdev
#検知したいデバイスのevent番号を書いてください
device = evdev.InputDevice('/dev/input/event1')
for event in device.read_loop():
if event.type == evdev.ecodes.EV_KEY:
if event.value == 1: #0:UP, 1:DOWN
if event.code == evdev.ecodes.KEY_KP1:
print('KEY1')
if event.code == evdev.ecodes.KEY_KP2:
print('KEY2')
if event.code == evdev.ecodes.KEY_KP3:
print('KEY3')
複数のデバイス(今回はマウスとテンキーの例)対応コードです。
様々な方法がありますが、今回はselectを採用しました。
https://python-evdev.readthedocs.io/en/latest/tutorial.html
#複数のデバイス読み込み対応(select使用)
import evdev
from select import select
#検知したいデバイスのevent番号を書いてください
devices = map(evdev.InputDevice, ('/dev/input/event0', '/dev/input/event1'))
devices = {dev.fd: dev for dev in devices}
while True:
r, w, x = select(devices, [], [])
for fd in r:
for event in devices[fd].read():
if event.type == evdev.ecodes.EV_KEY:
if event.value == 1: #0:UP, 1:DOWN
if event.code == evdev.ecodes.BTN_LEFT:
print('Left Click')
if event.code == evdev.ecodes.KEY_KP1:
print('KEY1')
ちょっと役立つクラゲの豆知識を記しておきます。
evdev.ecodes.KEY_KP1
は evdev.ecodes.ecodes['KEY_KP1']
でも同じ意味print(event.code)
で押したキーのコード番号を知ることができるprint(evdev.ecodes.KEY[コード番号])
で KEY_KP1
などのコード名がわかるevent番号が取れれば、USBでなくても無線テンキーや無線マウスなどもOKですし、Bluetoothデバイスもいけます。以下のように、100均で売っていたBluetoothボタンでも制御可能です。
https://monomonotech.jp/kurage/raspberrypi/daiso_btshutter.html
以上、evdevでキーボードやマウスのイベント取得でした!