Seite 1 von 1

[Linux] Einzelnes Zeichen lesen

Verfasst: Sonntag 20. Mai 2012, 10:05
von DominikST
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

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Sonntag 20. Mai 2012, 10:41
von deets

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Sonntag 20. Mai 2012, 11:08
von DominikST
Sehr gut, das Lesen klappt schonmal. Wie setze ich den Terminal-Modus nun wieder auf normal? Wenn ich nämlich das Spielfeld zeichne ist es extrem verzerrt...

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Sonntag 20. Mai 2012, 11:11
von deets
hm, vielleicht ist es besser gleich auf ncurses zu setzen?

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Sonntag 20. Mai 2012, 11:46
von snafu
DominikST hat geschrieben:Wie setze ich den Terminal-Modus nun wieder auf normal?
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).

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Montag 21. Mai 2012, 01:46
von lunar

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Montag 21. Mai 2012, 07:24
von snafu
@lunar: Warum verwendest du kein `tty.setraw()`?

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Montag 21. Mai 2012, 08:58
von lunar
@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.

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Montag 21. Mai 2012, 09:37
von jerch
Auch wenn schon etwas angestaubt - hier hatte ich mich mal an getch, getwch, kbhit und einem Kontextmanager für Terminalmodi probiert.

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Montag 21. Mai 2012, 10:11
von snafu
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.
Auf C-Ebene gibts doch mit `cfmakeraw()` etwas ähnliches, oder bringe ich da grad was durcheinander?

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Montag 21. Mai 2012, 15:54
von lunar
@snafu: Auch das kannte ich nicht, denn auch der C-Code, den ich als Vorlage verwendet habe, stammt nicht von mir. ;)

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Dienstag 22. Mai 2012, 17:12
von DominikST
@All

Danke, lunars Beispiel funktioniert ;)

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Mittwoch 23. Mai 2012, 12:01
von sma
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

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Mittwoch 23. Mai 2012, 14:49
von nomnom
Beispiel mit curses:

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()
Nicht sehr schön, und auch langsam.

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Mittwoch 23. Mai 2012, 15:48
von snafu
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.

Re: [Linux] Einzelnes Zeichen lesen

Verfasst: Mittwoch 23. Mai 2012, 16:23
von jerch
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.