tohutokonsome.hatenablog.com
以前、ラジコンのコントローラーをつくった記事を書きました。
その中で、キーボードから入力した値をもとに操作する機能は、以下の機能を参考にさせていただきました。
qiita.com
ただ、特定キーを押している状態、特定キーを離した状態というイベントを検出できると、よりコントローラぽくなるので、そんなことができる素敵なpythonモジュールがないかを探してました。
その中で、一番よさそうなpythonモジュールを見つけました。
が、想定通りの動作ができていないです。
解決策が見つけたら書くぞ!という意気込みを兼ねて、一旦記事に起こします。
pynput
キーボードやマウスを制御したり、入力内容の監視がシンプルにできるみたい。
キーロガーとかで使ったりするのかしら。
pypi.python.org
実行環境とインストール
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.10.5
BuildVersion: 14F1713
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ pyenv versions
system
3.5.1
3.5.1/envs/raspberry_3.5.1
3.5.2
pypy3-2.4.0
* raspberry_3.5.1 (set by /Users/konoe_mario/.pyenv/version)
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ sudo pip install pynput
サンプルコード
公式サイトの入力内容の監視を行うmサンプルコードをそのまま使用。
キー入力をlistenerがキャッチしてくれて、キー入力が行われると、on_pressに設定した関数を呼んで、キーが離されるとon_releaseに設定した関数が呼ばれる。
from pynput.keyboard import Key, Listener
def print_something():
'''
デバック用
'''
print('hi tohu!')
def on_press(key):
print_something()
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(key))
if key == Key.esc:
return False
if __name__ == '__main__':
with Listener(
on_press = on_press,
on_release= on_release
) as listener:
listener.join()
動かない
上記サンプルコードを、ターミナルで実行すると、「Command」「Shift」「Control」「option」などの入力は検知するのだけれども、通常の英数字のキー入力は検知してくれていない。
StackOverFlowにすごくそれっぽい質問もあがってたのだけれども、どうも原因が違うのではないかと思う。
stackoverflow.com
そもそも、on_press関数内のprint関数が英数字の場合は呼ばれていない。
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ python pynput_sample.py
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ python pynput_sample.py
hi tohu!
special key Key.cmd pressed
Key.cmd released
hi tohu!
special key Key.alt pressed
Key.alt released
hi tohu!
special key Key.shift pressed
Key.shift released
hi tohu!
special key Key.ctrl pressed
Key.ctrl released
1111
111
ugokanai
^[^[^[
^[[A
英数字の場合、コンソールに普通に入力できてしまうので、スペシャルキーとは挙動が違うのかもしれない。
ただ、StackOverFlowの質問を見る限り、特になんの制御もなくできてるっぽいんですよね。。。
sudoが足りなかった
sudo実行で普通にできました。Kさん、ありがとうございました。
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ sudo python pynput_sample.py
Password:
hi tohu!
alphanumeric key None pressed
a<0> released
hi tohu!
alphanumeric key None pressed
s<1> released
hi tohu!
alphanumeric key None pressed
d<2> released
hi tohu!
alphanumeric key None pressed
f<3> released
よくみるとKeyCodeを認識していない
うまくいってませんでした。。。
デバックでいろいろ見ていたのですが、OSXのキー入力のあたりから調べないとちょっと厳しそう。
進展がありしだい追記します。
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ sudo python pynput_sample.py
Password:
alphanumeric key None pressed ←押されたキー入力がNoneになっている。
2017.7.12追記
久しぶりに別件で起動してたら、KeyCodeを認識していることに気づいた。
なぜだろう。。。
(raspberry_3.5.1) masao-3:keyboard konoe_mario$ sudo python pynput_sample.py
alphanumeric key <13> pressed
w<13> released
alphanumeric key <1> pressed
s<1> released
alphanumeric key <0> pressed
a<0> released
alphanumeric key <2> pressed
d<2> released
その他候補
すっごい適当だけれども、pynput以外に試したものを、メモがてらに記載しています。
msvrct
Windowsでしか動かないので、採用しなかった。
keyboard
ホットキーの設定をしたり、キーイベントの監視をしたりいろいろとできそうだった。
pypi.python.org
が実行するとOSErrorになる。
OSError: [Errno 45] Operation not supported: '/dev/uinput'
公式をよく読んでみると、ちゃんと書いてありました。
「Hook and simulate keyboard events on Windows and Linux」
pythonのゲーム開発向けのモジュール。
導入するだけしてみたけれども、今回やりたいことだけにしては、大掛かりな印象を持った。
GUI画面を用いてコントローラーにするのには、いいのかもしれない。
でも、python3.5.1では、キー入力のイベント検知が動かなかった。
PySDL2
Pygameの後継らしい。
こっちではpython3.5.1でもキー入力イベントを検知することができた。