Hey Leute,
für ein kleines, konsolenbasiertes Spiel müsste ich ein einzelnes Zeichen von der Tastatur lesen. Es erscheint also eine Meldung auf dem Bildschirm und sobald der Benutzer ein Zeichen eintippt wird dieses Zeichen gespeichert und das Programm geht weiter, <Enter> muss zur Bestätigung nicht gedrückt werden. Geht sowas?
Betriebssystem ist Ubuntu 12.04, Python Version ist egal, 3.2 kann ich ein bisschen besser.
Danke schonmal
[Linux] Einzelnes Zeichen lesen
Versuch doch mal, den Code selbst nachzuvollziehen. Neben `tcgetattr()` gibt es im Modul termios auch die Funktion `tcsetattr()`. Dreimal darfst du raten, welche Attribute da wohl reingehören. Kleiner Tipp: Das Snippet bereitet das weitere Vorgehen quasi schon vor, aber hört dann irgendwie abrupt auf (warum auch immer).DominikST hat geschrieben:Wie setze ich den Terminal-Modus nun wieder auf normal?
@snafu: Ich wusste gar nicht nicht, dass es das gibt. Das Beispiel habe ich direkt von C übertragen, ohne mir weitere Gedanken zu machen. Ich habe das Beispiel aktualisiert, so dass es "tty.setraw()" benutzt.
Auf C-Ebene gibts doch mit `cfmakeraw()` etwas ähnliches, oder bringe ich da grad was durcheinander?lunar hat geschrieben:@snafu: Ich wusste gar nicht nicht, dass es das gibt. Das Beispiel habe ich direkt von C übertragen, ohne mir weitere Gedanken zu machen.
@snafu: Auch das kannte ich nicht, denn auch der C-Code, den ich als Vorlage verwendet habe, stammt nicht von mir.
Ich würde ebenfalls empfehlen, http://docs.python.org/library/curses.html zu benutzen, und nicht am Terminal auf der wirklich untersten Betriebssystemebene zu fummeln. Curses versucht ja gerade, von den Eigenheiten der Terminals zu abstrahieren und läuft zumindest problemlos unter allen Unix-artigen Betriebssystemen inklusive OS X. Einig für Windows muss man etwas tun (siehe http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses).
Stefan
Stefan
Beispiel mit curses:
Nicht sehr schön, und auch langsam.
Code: Alles auswählen
import curses
from sys import stdin, stdout
def read_character(prompt=''):
print(prompt, end='')
stdout.flush()
curses.initscr()
curses.cbreak()
try:
return stdin.read(1)
finally: # Trick mit try / finally von Lunar
curses.nocbreak()
curses.endwin()
Ich finde, das `curses`-Beispiel ist auch nicht wesentlich "highleveliger" als der `tc[get|set]attr()`-Ansatz aus lunars Beispiel. Das genannte `tty.setraw()` übernimmt nochmal das Setzen der passenden Attribute für einen, sodass man zumindest keine Konstanten und deren Anwendung auswendig wissen (bzw per Copy&Paste einfügen) muss.
Man kann's natürlich auch mit `curses` machen und erstmal die Initialisierungsroutine der Bibliothek aufrufen und so, aber soviel gewonnen ist dadurch glaube ich auch nicht.
Es kommt natürlich immer darauf an, ob man wirklich nur diese eine Sache machen möchte, oder ob man `curses` - wenn einmal initialisiert - nicht auch für weitere ähnliche Aktionen im Programm verwenden will.
Man kann's natürlich auch mit `curses` machen und erstmal die Initialisierungsroutine der Bibliothek aufrufen und so, aber soviel gewonnen ist dadurch glaube ich auch nicht.
Es kommt natürlich immer darauf an, ob man wirklich nur diese eine Sache machen möchte, oder ob man `curses` - wenn einmal initialisiert - nicht auch für weitere ähnliche Aktionen im Programm verwenden will.
Ich weiss nicht, ob der Bug im curses-Modul noch existiert, allerdings ging früher das wiederholte Initialisieren des Terminalscreens nicht, sondern quittierte das ab dem 2nd Versuch mit einem segfault, während in C das kein Problem ist.