pygame
などの巨大な肥大化したモジュールなしでpythonでキーリスナーを実行する方法はありますか?
たとえば、 a コンソールに印刷するキー
キーが押されました!
また、矢印キー/スペースバー/シフトキーもリッスンする必要があります。
残念ながら、そうするのはそれほど簡単ではありません。何らかのテキストユーザーインターフェイスを作成しようとしている場合は、 curses
を調べてください。ターミナルに通常表示するようなものを表示したいが、そのような入力が必要な場合は、 termios
で作業する必要があります。 Python。残念ながら、これらのオプションはどちらもそれほど単純ではありません。また、Windowsでは機能しません。 Windowsで動作させる必要がある場合は、curses
ではなくtermios
または pywin32 の代わりに PDCurses を使用する必要があります。 。
これをうまく機能させることができました。入力したキーの16進表現を出力します。質問のコメントで述べたように、矢印は扱いにくいです。同意すると思います。
#!/usr/bin/env python
import sys
import termios
import contextlib
@contextlib.contextmanager
def raw_mode(file):
old_attrs = termios.tcgetattr(file.fileno())
new_attrs = old_attrs[:]
new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)
try:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)
yield
finally:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)
def main():
print 'exit with ^C or ^D'
with raw_mode(sys.stdin):
try:
while True:
ch = sys.stdin.read(1)
if not ch or ch == chr(4):
break
print '%02x' % ord(ch),
except (KeyboardInterrupt, EOFError):
pass
if __name__ == '__main__':
main()
Windowsでそれを行う方法は次のとおりです。
"""
Display series of numbers in infinite loop
Listen to key "s" to stop
Only works on Windows because listening to keys
is platform dependent
"""
# msvcrt is a windows specific native module
import msvcrt
import time
# asks whether a key has been acquired
def kbfunc():
#this is boolean for whether the keyboard has bene hit
x = msvcrt.kbhit()
if x:
#getch acquires the character encoded in binary ASCII
ret = msvcrt.getch()
else:
ret = False
return ret
#begin the counter
number = 1
#infinite loop
while True:
#acquire the keyboard hit if exists
x = kbfunc()
#if we got a keyboard hit
if x != False and x.decode() == 's':
#we got the key!
#because x is a binary, we need to decode to string
#use the decode() which is part of the binary object
#by default, decodes via utf8
#concatenation auto adds a space in between
print ("STOPPING, KEY:", x.decode())
#break loop
break
else:
#prints the number
print (number)
#increment, there's no ++ in python
number += 1
#wait half a second
time.sleep(0.5)
Pythonでキーリスナーを実行する方法があります。この機能は、 pynput から利用できます。
コマンドライン:
> pip install pynput
Pythonコード:
from pynput import ket,listener
# your code here
Sudo pip install keyboard
この小さなPythonライブラリを使用してキーボードを完全に制御します。グローバルイベントをフックし、ホットキーを登録し、キーの押下をシミュレートします。
すべてのキーボードのグローバルイベントフック(フォーカスに関係なくキーをキャプチャします)。キーボードイベントをリッスンして送信します。 WindowsおよびLinux(Sudoが必要)で動作し、実験的なOS Xサポート(@glitchassassin!に感謝)。純粋なPython、コンパイルするCモジュールなし。依存関係はありません。インストールとデプロイは簡単で、ファイルをコピーするだけです。 Python 2および3.複雑なホットキーのサポート(Ctrl + Shift + M、Ctrl + Spaceなど)、タイムアウトの制御可能。高レベルAPI(記録と再生、add_abbreviationなど)を含む。キーをマップする実際には、完全な国際化サポート(例:Ctrl +ç)を使用してレイアウト内にあります。イベントは別のスレッドで自動的にキャプチャされ、メインプログラムをブロックしません。テストおよび文書化されます。 pyHook)。プロジェクトマウス(pip install mouse)を介して利用可能なマウスサポート。
README.md から:
import keyboard
keyboard.press_and_release('shift+s, space')
keyboard.write('The quick brown fox jumps over the lazy dog.')
# Press PAGE UP then PAGE DOWN to type "foobar".
keyboard.add_hotkey('page up, page down', lambda: keyboard.write('foobar'))
# Blocks until you press esc.
keyboard.wait('esc')
# Record events until 'esc' is pressed.
recorded = keyboard.record(until='esc')
# Then replay back at three times the speed.
keyboard.play(recorded, speed_factor=3)
# Type @@ then press space to replace with abbreviation.
keyboard.add_abbreviation('@@', '[email protected]')
# Block forever.
keyboard.wait()
ウィンドウフォーカスのないシンプルなソリューションを探していました。 Jaykの答え、pynputは私にぴったりです。これが私がそれをどのように使用するかの例です。
from pynput import keyboard
def on_press(key):
try: k = key.char # single-char keys
except: k = key.name # other keys
if key == keyboard.Key.esc: return False # stop listener
if k in ['1', '2', 'left', 'right']: # keys interested
# self.keys.append(k) # store it in global-like variable
print('Key pressed: ' + k)
return False # remove this if want more keys
lis = keyboard.Listener(on_press=on_press)
lis.start() # start to listen on a separate thread
lis.join() # no this if main thread is polling self.keys
キーボードモジュールを使用してキーボードイベントをキャプチャするのが好きですが、record()
のような配列を返すため、[KeyboardEvent("A"), KeyboardEvent("~")]
関数は好きではありません。したがって、キーボードイベントを記録するには、次のようにキーボードモジュールとスレッド化モジュールを同時に使用します。
import keyboard
import string
from threading import *
# I can't find a complete list of keyboard keys, so this will have to do:
keys = list(string.ascii_lowercase)
"""
Optional code(extra keys):
keys.append("space_bar")
keys.append("backspace")
keys.append("shift")
keys.append("esc")
"""
def listen(key):
while True:
keyboard.wait(key)
print("[+] Pressed",key)
threads = [Thread(target=listen, kwargs={"key":key}) for key in keys]
for thread in threads:
thread.start()