Polling the keyboard (detect a keypress) in python
The standard approach is to use the select module.
However, this doesn't work on Windows. For that, you can use the msvcrt module's keyboard polling.
Often, this is done with multiple threads -- one per device being "watched" plus the background processes that might need to be interrupted by the device.
How do I use the Python keyboard module to detect a key press?
I took a look at the documentation located here https://github.com/boppreh/keyboard.
I ran and tested this code on python 3.9
import keyboard
from functools import partial
num = ""
def add(i):
global num
num += str(i)
print(num, end='\r')
for i in range(10): # numbers 0...9
keyboard.add_hotkey(str(i), partial(add, i)) # add hotkeys
keyboard.wait('enter') # block process until "ENTER" is pressed
print("\nNum:{}".format(num))
You could additionally unhook the hotkeys by calling keyboard.unhook_all_hotkeys()
after grabbing the number. I imagine you could wait on "+" and "-" if you wanted to implement addition and subtraction of numbers.
How can I detect a key pressed during a pause in python?
While Matteo's answer will do the job, you might still wait a small amount of time after you press q
before the polling thread stops. That's because the polling thread waits one second before checking the run
variable.
If you instead of a thread, use a Process
from the multiprocessing
module, you can terminate it as soon as the user presses q
and avoid the extra wait time.
Here is an example:
import keyboard
from multiprocessing import Process
import time
def press_a_every_second():
while True:
time.sleep(1)
keyboard.press_and_release('a')
if __name__ == "__main__":
worker = Process(target=press_a_every_second)
keyboard.add_hotkey('q', worker.terminate)
worker.start()
worker.join()
Key Listeners in python?
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()
Related Topics
Plot Different Color for Different Categorical Levels Using Matplotlib
How to Check Type of Files Without Extensions
What Does the Caret (^) Operator Do
Concatenate Rows of Two Dataframes in Pandas
Skip Rows During CSV Import Pandas
How to Keep Track of Class Instances
Return in Generator Together with Yield
Id' Is a Bad Variable Name in Python
What Do Square Brackets, "[]", Mean in Function/Class Documentation
How to Run Pip from Different Versions of Python Using the Python Command
Why Does Using 'Arg=None' Fix Python's Mutable Default Argument Issue
How to Connect to Tor Browser Using Python
How to Make a Custom Activation Function with Only Python in Tensorflow
How to Use Jdbc Source to Write and Read Data in (Py)Spark