En utilisant un bon module léger de révérence, vous pouvez faire quelque chose comme ceci (tiré de leur répertoire examples/):
from curtsies import Input
def main():
with Input(keynames='curses') as input_generator:
for e in input_generator:
print(repr(e))
if __name__ == '__main__':
main()
Ainsi, appuyer sur les touches de votre clavier vous donne quelque chose comme ceci :
'a'
's'
'KEY_F(1)'
'KEY_F(2)'
'KEY_F(3)'
'KEY_F(4)'
'KEY_F(5)'
'KEY_LEFT'
'KEY_DOWN'
'KEY_UP'
'KEY_RIGHT'
'KEY_NPAGE'
'\n'
curtsies est utilisé par bpython comme une abstraction de bas niveau des éléments liés au terminal.
Le problème de base du décodage de l'entrée est que dans différents terminaux et programmes d'émulation de terminal comme xterm
ou gnome-terminals
physiquement les mêmes clés produisent des séquences de codes de touches différentes. C'est pourquoi il faut savoir quels paramètres de terminal doivent être utilisés pour décoder l'entrée. Un tel module aide à faire abstraction de ces détails sanglants.
Il s'agit d'une boucle simple qui mettra stdin en mode brut (désactivant la mise en mémoire tampon pour que vous n'ayez pas à appuyer sur Entrée) pour obtenir des caractères uniques. Vous devriez faire quelque chose de plus intelligent (comme un with
pour le désactiver) mais vous voyez l'idée ici :
import tty
import sys
import termios
orig_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
x = 0
while x != chr(27): # ESC
x=sys.stdin.read(1)[0]
print("You pressed", x)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings)
Je pense que vous devriez boucler pour détecter les versions de clé en Python.
ETA quelques explications supplémentaires :
Sous Linux, l'entrée de votre programme sera mise en mémoire tampon en ligne . Cela signifie que le système d'exploitation mettra en mémoire tampon l'entrée jusqu'à ce qu'il ait une ligne entière, de sorte que votre programme ne verra même rien de ce que l'utilisateur a tapé jusqu'à ce que l'utilisateur appuie également sur "Entrée". En d'autres termes, si votre programme s'attend à ce que l'utilisateur tape 'w' et que l'utilisateur le fasse, 'w' restera dans la mémoire tampon du système d'exploitation jusqu'à ce que l'utilisateur appuie sur 'enter'. À ce stade, la ligne entière est livrée à votre programme, vous obtiendrez donc la chaîne "w\n" comme entrée de l'utilisateur.
Vous pouvez désactiver cela en mettant le tty en mode brut . Vous faites cela avec la fonction Python tty.setcbreak
qui appellera le pilote tty sous Linux pour lui dire d'arrêter la mise en mémoire tampon. Je lui ai passé le sys.stdin
argument pour lui dire pour quel flux je voulais désactiver la mise en mémoire tampon. Donc après le tty.setcbreak
appel, la boucle ci-dessus vous donnera une sortie pour chaque touche appuyée par l'utilisateur.
Une complication, cependant, est qu'une fois votre programme terminé, le tty est toujours en mode brut. Vous trouverez généralement cela insatisfaisant, car vous n'obtenez aucune puissance offerte par les paramètres de terminal modernes (comme lorsque vous utilisez des séquences de contrôle ou d'échappement). Par exemple, notez que vous pourriez avoir des difficultés à quitter le programme avec ctrl-C
. Par conséquent, vous devez remettre le terminal en mode cuit une fois que vous avez fini de lire les caractères saisis. Le termios.tcsetattr
l'appel dit simplement "remettez le terminal comme je l'ai trouvé". Il sait comment faire cela en appelant d'abord termios.tcgetattr
au début du programme qui dit "dites-moi tous les paramètres actuels du terminal".
Une fois que vous avez compris tout cela, vous devriez facilement pouvoir encapsuler la fonctionnalité dans une fonction adaptée à votre programme.
stdin
est le flux que l'entrée vous vient de l'utilisateur. Wikipédia peut vous en dire plus sur les flux standards.