Programm zum Tastatur abfragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
luckretisgni
User
Beiträge: 1
Registriert: Dienstag 18. April 2017, 12:38

Ich möchte ein Programm schreiben, bei dem etwas passieren soll wenn eine Taste auf der Tastatur gedrückt wird.
Nun muss ich eine Funktion schreiben, die eine Variable als TRUE setzt, wenn die Leertaste gedrückt wird und sie (die Variable) sonst auf FALSE setzt.
Hat jemand eine Idee (oder schreibt einfach selber dieses Programm :D :lol: )

Vielen >Dank< schon mal
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Etwas unschön ist es, andere Programmbibliothen dazu zu laden oder eine GUI wie tkinter zu verwenden, wenn man auf Tastendrücke reagieren will.

Wenn man mit sys.stdin.read(1) die Tastatur abfrägt, dann werden die Buchstaben auf dem Terminal ausgegeben und außerdem gewartet bis man die Enter Taste gedrückt hat. Das will man natürlich nicht haben.

Für Windows kan man msvcrt.getch() benützen, für Linux, sofern es POSIX termios unterstützt, kann man Terminal Attribute so umstellen, dass man mit sys.stdin.read(1) die Tastatur ohne Echo und Warten auf Enter Taste abfragen kann.

Der Code dafür:

Code: Alles auswählen

class _Getch:
    """Gets a single character from standard input.  Does not echo to the
screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self): return self.impl()


class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()


getch = _Getch()

# --- Test der getch Funktion -------------

while(1):
    c = getch()
    if c != '':
        print("Character: ",c)
Quele: http://stackoverflow.com/questions/5103 ... m-the-user
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: was hast Du denn da ausgegraben? Ein import in __init__ nur um zu prüfen, ob sich die Klasse initialisieren läßt? Passt natürlich zu Deinem Verständnis von Klassen, aber dazu nimmt man keine Klassen. Das ist einfach nur unleserlich, umständlich und sowas von weit weg, wie man normalerweise Python programmiert. Importe gehören an den Anfang jeder Datei, dass man gleich sieht, welche Abhängigkeiten bestehen und Importfehler möglichst früh auftreten.

Mal sehen, was Du daran auszusetzen hast:

Code: Alles auswählen

try:
    from msvcrt import getch
except ImportError:
    import sys, tty, termios
    def getch():
        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
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Sirius3: ja diese Version war nicht gut engeneered. Das ist dann die vom Code her bessere Variante:

Code: Alles auswählen

def _find_getch():
    try:
        import termios
    except ImportError:
        # Non-POSIX. Return msvcrt's (Windows') getch.
        import msvcrt
        return msvcrt.getch

    # POSIX system. Create and return a getch that manipulates the tty.
    import sys, tty
    def _getch():
        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

    return _getch

getch = _find_getch()

# --- Test der getch Funktion -------------
 
while(1):
    c = getch()
    if c != '':
        if c == '\x03':
            break
        print("Character: ",c)
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: die vom Code her bessere Variante hab ich doch schon gezeigt. Warum packst Du das definieren der getch-Funktion in eine weitere Funktion ein? Das ist doch völlig überflüssig.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Sirius3: ich mache da gar nichts, der Code ist nicht von mir sondern von hier: http://stackoverflow.com/questions/5103 ... m-the-user
BlackJack

@Alfons Mittelmeyer: Na dann ist halt die Frage warum den Code von dort nach hier kopierst, wo's doch hier schon eine Lösung von Sirius gab.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: deshalb habe ich ja auch beim ersten Post "ausgegraben" geschrieben. Dass Du den zweiten Versuch auch von dort abgeschrieben hast, habe ich nicht nachgeschaut. Macht es aber auch nicht besser, dass Du nicht erklären kannst, was der Vorteil einer fetch_getch-Funktion ist.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sorry, hatte nur eine kurzen Blick auf den Code von Sirius geworfen ohne ihn durchzulesen. War mir so, als ob das nur ein Teil von einem code wäre. Habe ihn jetzt durchgelesen. Ja der Code ist komplett und gut überlegt. Besser als das was ich dann noch reinkopiert hatte. Das war dann unnötig.
Antworten