可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is there a way to do key listeners in python without a huge bloated module such as pygame
?
An example would be, when I pressed the a key it would print to the console
The a key was pressed!
It should also listen for the arrow keys/spacebar/shift key.
回答1:
It's unfortunately not so easy to do that. If you're trying to make some sort of text user interface, you may want to look into curses
. If you want to display things like you normally would in a terminal, but want input like that, then you'll have to work with termios
, which unfortunately appears to be poorly documented in Python. Neither of these options are that simple, though, unfortunately. Additionally, they do not work under Windows; if you need them to work under Windows, you'll have to use PDCurses as a replacement for curses
or pywin32 rather than termios
.
I was able to get this working decently. It prints out the hexadecimal representation of keys you type. As I said in the comments of your question, arrows are tricky; I think you'll agree.
#!/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()
回答2:
Here's how can do it on 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)
回答3:
There is a way to do key listeners in python. This functionality is available through pynput.
Command line:
> pip install pynput
Python code:
from pynput import ket,listener # your code here
回答4:
I was searching for a simple solution without window focus. Jayk's answer, pynput, works perfect for me. Here is the example how I use it.
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
回答5:
keyboard
Take full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more.
From 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('@@', 'my.long.email@example.com') # Block forever. keyboard.wait()
回答6:
Although I like using the keyboard module to capture keyboard events, I don't like its record()
function because it returns an array like [KeyboardEvent("A"), KeyboardEvent("~")]
, which I find kind of hard to read. So, to record keyboard events, I like to use the keyboard module and the threading module simultaneously, like this:
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()