I have problem with keyboard input in Python. I tried raw_input and it is called only once. But I want to read keyboard input every time user press any key. How can I do it? Thanks for answers.
-
Maybe a loop will help to read repeatedly from the keyboard – Thomas Junk Sep 19 '15 at 17:42
-
You can do this with `tkinter` but that may be overkill. In what context are you trying to do this? – saulspatz Sep 19 '15 at 17:42
-
1Your question is not clear... `raw_input` *does* read the keyboard input, any key press until the user hits "Enter". You should put some effort in describing what is it that you want to achieve. – Nir Alfasi Sep 19 '15 at 17:42
-
1possible duplicate of http://stackoverflow.com/questions/12175964/python-method-for-reading-keypress – Azsgy Sep 19 '15 at 17:44
-
I tried this http://rosettacode.org/wiki/Keyboard_input/Keypress_check#Python but it is not working. I typed to console is it wrong? – Václav Pavlíček Sep 19 '15 at 17:51
-
@alfasin I think what the OP is saying is quite clear. He wants to read the input EVERY TIME the user presses a key. raw_input only reads the input ONCE -- after the user presses the Enter key. It's true that raw_input reads all the input, but it only does it once. – saulspatz Sep 19 '15 at 17:51
-
@saulspatz and Vaclav, please check my answer edit. – Sep 19 '15 at 17:53
-
1@Václav Pavlíček When you say, "it is not working" that isn't very informative. What is happening? BTW, are you using Windows or some other OS? – saulspatz Sep 19 '15 at 17:55
-
Re-check my answer. Now it definitely works. I've just run it on my Mac. – Sep 19 '15 at 18:09
-
I tried it on Mint and I want to print result to console. I tried breakpoint to return ch but it never stopped. – Václav Pavlíček Sep 19 '15 at 18:16
2 Answers
So for instance you have a Python code like this:
file1.py
#!/bin/python
... do some stuff...
And at a certain point of the document you want to always check for input:
while True:
input = raw_input(">>>")
... do something with the input...
That will always wait for input. You can thread that infinite loop as a separate process and do other things in the meanwhile, so that the user input can have an effect in the tasks you are doing.
If you instead want to ask for input ONLY when a key is pressed, and do that as a loop, with this code (taken from this ActiveState recipe by Steven D'Aprano) you can wait for the key press to happen, and then ask for an input, execute a task and return back to the previous state.
import sys try: import tty, termios except ImportError: # Probably Windows. try: import msvcrt except ImportError: # FIXME what to do on other platforms? # Just give up here. raise ImportError('getch not available') else: getch = msvcrt.getch else: def getch(): """getch() -> key character Read a single keypress from stdin 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. If the pressed key was a modifier key, nothing will be detected; if it were a special function key, it may return the first character of of an escape sequence, leaving additional characters in the buffer. """ 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
So how to deal with this? Well, now just call getch()
every time you want to wait for a key press. Just like this:
while True:
getch() # this also returns the key pressed, if you want to store it
input = raw_input("Enter input")
do_whatever_with_it
You can also thread that and do other tasks in the meanwhile.
Remember that Python 3.x does no longer use raw_input, but instead simply input().

- 1
- 1
-
3@alfasin Python 3 is indeed relevant, because this is an open Q&A site, and more people than the OP visit the page. They must notice that buit-in method will only work in Py2.x. And the OP can know that too. Info does _not_ hurt. – Sep 19 '15 at 17:57
-
There's a lot of interesting info which is not relevant to the question that you can add. About other programming languages too... Please keep the answer relevant to the question. – Nir Alfasi Sep 19 '15 at 17:58
-
@J.C. Rocamonde Please reformat the code in your answer, which looks excellent, BTW. – saulspatz Sep 19 '15 at 18:11
-
When i run it it throws this error: termios.error: (25, 'Inappropriate ioctl for device') – Václav Pavlíček Sep 19 '15 at 18:19
-
@VáclavPavlíček that's weird, its working for me. Just let me check it and solve your problem. Don't worry, we'll sort this out together. – Sep 19 '15 at 18:20
-
@VáclavPavlíček exactly, which line does it tell you the error came from? Can you paste the full error message? – Sep 19 '15 at 18:22
-
@VáclavPavlíček, you are not running the code from a terminal? – Padraic Cunningham Sep 19 '15 at 18:23
-
-
@J.C.Rocamonde, unless where you are running the code is a tty then it is going to fail. – Padraic Cunningham Sep 19 '15 at 18:25
-
It throws error only in Pycharm but in command line it runs very well! Thank you for all! – Václav Pavlíček Sep 19 '15 at 18:26
-
@VáclavPavlíček just here to help! Do you want me to pass the loop to a thread? I can write an example for you – Sep 19 '15 at 18:27
-
3You should provide a link to where you took the code from http://code.activestate.com/recipes/577977-get-single-keypress/ – Padraic Cunningham Sep 19 '15 at 18:34
-
1
In python2.x, simply use an infinite while
loop with conditional break
:
In [11]: while True:
...: k = raw_input('> ')
...: if k == 'q':
...: break;
...: #do-something
> test
> q
In [12]:

- 32,744
- 15
- 77
- 108
-
6I don't think this does what the OP wants. You have to press
after each key. I think he wants to intercept individual key presses, like `getch` in C. (If `getch` is the function I'm thinking of.) – saulspatz Sep 19 '15 at 17:47 -
@saulspatz Not sure, yet I may guess the OP doesn't know `getch` in C yet ;) – zhangxaochen Sep 19 '15 at 17:51
-
I don't think he knows it either, and since he's trying to write in python, it wouldn't do him any good if he did. I'm not being critical of you, just trying to help out the OP. :-) – saulspatz Sep 19 '15 at 18:07