web-dev-qa-db-fra.com

raw_input dans python sans appuyer sur Entrée

J'utilise raw_input in Python pour interagir avec l'utilisateur dans Shell.

c = raw_input('Press s or n to continue:')
if c.upper() == 'S':
    print 'YES'

Cela fonctionne comme prévu, mais l'utilisateur doit appuyer sur Entrée dans le Shell après avoir appuyé sur 's'. Existe-t-il un moyen d'accomplir ce dont j'ai besoin à partir d'une entrée utilisateur sans avoir à appuyer sur Entrée dans le shell? J'utilise des machines * nixes.

Sous Windows, vous avez besoin du module msvcrt, plus précisément, il semble, d'après la façon dont vous décrivez votre problème, la fonction msvcrt.getch :

Lisez une touche et retournez le caractère résultant. Rien n'est répercuté sur la console. Cet appel se bloquera si une touche n'est pas déjà disponible, mais n'attendra pas que vous appuyiez sur Entrée.

(etc - voir les documents que je viens de signaler). Pour Unix, voir par ex. cette recette pour un moyen simple de construire une fonction getch similaire (voir aussi plusieurs alternatives & c dans le fil de commentaire de cette recette).

19
Alex Martelli

Python ne fournit pas de solution multiplateforme prête à l'emploi.
Si vous êtes sous Windows, vous pouvez essayer msvcrt avec:

import msvcrt
print 'Press s or n to continue:\n'
input_char = msvcrt.getch()
if input_char.upper() == 'S': 
   print 'YES'
12
systempuntoout

les malédictions peuvent aussi le faire:

import curses, time

def input_char(message):
    try:
        win = curses.initscr()
        win.addstr(0, 0, message)
        while True: 
            ch = win.getch()
            if ch in range(32, 127): 
                break
            time.sleep(0.05)
    finally:
        curses.endwin()
    return chr(ch)

c = input_char('Do you want to continue? y/[n]')
if c.lower() in ['y', 'yes']:
    print('yes')
else:
    print('no (got {})'.format(c))
5
user2660966

Au lieu du module msvcrt, vous pouvez également utiliser WConio :

>>> import WConio
>>> ans = WConio.getkey()
>>> ans
'y'
3
John Howard

Pour obtenir un seul caractère, j'ai utilisé getch , mais je ne sais pas si cela fonctionne sous Windows.

2
Derek Kurth

Sur une note latérale, msvcrt.kbhit () renvoie une valeur booléenne déterminant si une touche du clavier est actuellement enfoncée.

Donc, si vous créez un jeu ou quelque chose et que vous souhaitez que les touches soient exécutées sans interrompre complètement le jeu, vous pouvez utiliser kbhit () dans une instruction if pour vous assurer que la clé n'est récupérée que si l'utilisateur souhaite réellement faire quelque chose. .

Un exemple dans Python 3:

# this would be in some kind of check_input function
if msvcrt.kbhit():
    key = msvcrt.getch().decode("utf-8").lower() # getch() returns bytes data that we need to decode in order to read properly. i also forced lowercase which is optional but recommended
    if key == "w": # here 'w' is used as an example
        # do stuff
    Elif key == "a":
        # do other stuff
    Elif key == "j":
        # you get the point
1
Nytra

Je sais que c'est vieux, mais la solution n'était pas assez bonne pour moi. J'ai besoin de la solution pour prendre en charge plusieurs plates-formes et sans installer aucun Python) externe = packages .

Ma solution pour cela, au cas où quelqu'un d'autre tomberait sur ce post

Référence: https://github.com/unfor19/mg-tools/blob/master/mgtools/get_key_pressed.py

from tkinter import Tk, Frame


def __set_key(e, root):
    """
    e - event with attribute 'char', the released key
    """
    global key_pressed
    if e.char:
        key_pressed = e.char
        root.destroy()


def get_key(msg="Press any key ...", time_to_sleep=3):
    """
    msg - set to empty string if you don't want to print anything
    time_to_sleep - default 3 seconds
    """
    global key_pressed
    if msg:
        print(msg)
    key_pressed = None
    root = Tk()
    root.overrideredirect(True)
    frame = Frame(root, width=0, height=0)
    frame.bind("<KeyRelease>", lambda f: __set_key(f, root))
    frame.pack()
    root.focus_set()
    frame.focus_set()
    frame.focus_force()  # doesn't work in a while loop without it
    root.after(time_to_sleep * 1000, func=root.destroy)
    root.mainloop()
    root = None  # just in case
    return key_pressed


def __main():
        c = None
        while not c:
                c = get_key("Choose your weapon ... ", 2)
        print(c)

if __name__ == "__main__":
    __main()
0
Meir Gabay