Actually in the meantime (almost 10 years from the start of this thread) a cross-platform module named pynput appeared. Below a first cut - i.e. that works with lowercase 's' only. I have tested it on Windows but I am almost 100% positive that it should work on Linux.
from pynput import keyboard
print('Press s or n to continue:')
with keyboard.Events() as events:
# Block for as much as possible
event = events.get(1e6)
if event.key == keyboard.KeyCode.from_char('s'):
print("YES")
Answer from Adrian Rosoga on Stack OverflowActually in the meantime (almost 10 years from the start of this thread) a cross-platform module named pynput appeared. Below a first cut - i.e. that works with lowercase 's' only. I have tested it on Windows but I am almost 100% positive that it should work on Linux.
from pynput import keyboard
print('Press s or n to continue:')
with keyboard.Events() as events:
# Block for as much as possible
event = events.get(1e6)
if event.key == keyboard.KeyCode.from_char('s'):
print("YES")
Under Windows, you need the msvcrt module, specifically, it seems from the way you describe your problem, the function msvcrt.getch:
Read a keypress and return the resulting character. Nothing is echoed to the console. This call will block if a keypress is not already available, but will not wait for Enter to be pressed.
(etc -- see the docs I just pointed to). For Unix, see e.g. this recipe for a simple way to build a similar getch function (see also several alternatives &c in the comment thread of that recipe).
Howdy,
Do you know if there is a way to accept user's input without pressing enter?
I am trying to exit a while loop by pressing the key "q" but with the input() function I have to press enter.
I would like to use standard Python modules (if possible) and not install anything else with pip.
Thank you!
Edit: I'm using Python3.8 on Unix
Jupyter Python Script waiting keyboard input without Enter strike
Get input without pressing enter
while loop - How to accept input without the need to press enter Python 3 - Stack Overflow
What's a python function that reads any keyboard pressed, without pressing enter after it?
You can also use https://pypi.org/project/pynput/
More on reddit.comHey, so I would like to get the input without the user having to press enter. I was wondering if there was any way to just trigger the input when the user enters a character. Thanks in advance!
input() memorizes the key you press only if you also press enter after it. I'm trying to make a CLI game and I looked up on how I could get the keyboard input and found this answer on stackoverflow explaining something about multi-threaded input which is just what i needed (the third answer here https://stackoverflow.com/questions/5404068/how-to-read-keyboard-input)
however, while it is true that it's multi-threaded and it doesn't stop the program for you to enter the input, for your input to be memorized in the inputQueue you also need to press enter after entering a key. Is there a function that memorizes your input without pressing enter, just memorizes the first key you press? So that I could replace the input() in the following function with that method
def read_kbd_input(inputQueue):
print('Ready for keyboard input:')
while (True):
input_str = input() ##replace here ##
inputQueue.put(input_str)You can also use https://pypi.org/project/pynput/
Yes, I did this as part of an ascii Tetris game. If you're on Windows, it's trivial:
from msvcrt import kbhit, getch
On Mac/Linux it requires first debuffering stdin in order to read characters one at a time, then rebuffering it when your program exits to avoid breaking the terminal, although I guess that's not strictly required:
import sys, termios, atexit
from select import select
# Save normal terminal settings
fd = sys.stdin.fileno()
old_term = termios.tcgetattr(fd)
def set_normal_term():
termios.tcsetattr(fd, termios.TCSAFLUSH, old_term)
# Debuffer new terminal until exit
new_term = termios.tcgetattr(fd)
new_term[3] = (new_term[3] & ~termios.ICANON & ~termios.ECHO)
def set_curses_term():
termios.tcsetattr(fd, termios.TCSAFLUSH, new_term)
atexit.register(set_normal_term)
set_curses_term()
def kbhit():
dr,dw,de = select([sys.stdin], [], [], 0)
return dr != []
def getch():
return sys.stdin.read(1)
Then, regardless of OS, your main loop would look something like this:
while not game_over:
if kbhit():
key = getch()
handle_keypress(key)
You can define your own version of getch using the termios, sys and tty packages:
def getch():
import termios
import sys, tty
def _getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
return _getch()
This is a tested (on RPi, Py 3) code that can read a specified length of chars without need to hit Enter button
But consider one thing :
This must run on terminal otherwise raises an error
import termios, sys , tty
def _getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1) #This number represents the length
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
getch = _getch()
print(getch)