keypress event bekommen - nicht blockieren

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
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo, wie bekomme ich
a) in Windows
b) in Linux

ein KeyEvent, ohne dabei das Programm zu blockieren:

Code: Alles auswählen

while 1:
   print "key=" getkey()
Wenn kein key gedrückt wurde, sollte dann einfach "key=" stehen. raw_input und so weiter verlangen ja alle, dass etwas mit enter abgeschlossen ist.
in Linux: sys.stdin.read(1) wartet ebenfalls so lange, bis es mit enter quittiert wurde.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mit pygame geht so etwas.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hyperion hat geschrieben:Mit pygame geht so etwas.
Danke für die prompte Antwort. Das verstehe ich nicht, dass so eine einfache Sache nicht einfach in Python drin ist. Vielleicht geht das vom Betriebssystem selbst nicht so leicht? dass die nur dann den Tastaturpuffer weitergeben, wenn ein Return gedrückt wurde.

Ich möchte das in einem einfachen Konsolenprogramm drin haben.
pseudocode:

Code: Alles auswählen

while 1:
    dosomethingveryoften()
    if mygetkeypress().lower() in ["qx"]:
        print "quit"
        break
Auch wenns andere Lösungen für das Abbrechen geben würde, würde mich diese spezielle Lösung jetzt interessieren.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

K.A. Du kannst Dir ansonsten auch mal curses und die div darauf aufbauenden Libs angucken. Evtl. können die so etwas auch. Andererseits weiß ich nicht, wie es da mit der Portabilität aussieht.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Francesco: Wie Du schon richtig vermutest ist diese "einfache" Sache nicht wirklich einfach. Das hängt vom Betriebssystem ab und dort auch von wo man die Eingabe bekommen möchte -- Terminal, Fenstermanager, direkt aus dem Tastaturpuffer… Portabel ist das nicht so einfach zu lösen. Eine standardisierte Schnittstelle gibt's wohl nicht wirklich.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

BlackJack hat geschrieben:@Francesco: Wie Du schon richtig vermutest ist diese "einfache" Sache nicht wirklich einfach. Das hängt vom Betriebssystem ab und dort auch von wo man die Eingabe bekommen möchte -- Terminal, Fenstermanager, direkt aus dem Tastaturpuffer… Portabel ist das nicht so einfach zu lösen. Eine standardisierte Schnittstelle gibt's wohl nicht wirklich.
@BlackJack: Schade, mich hats ja auch schon gewundert, warum im google so schwer was zu finden ist. Ich frage mich: Wie breche ich das Programm sonst elegant ab? Es soll einfach dann abgebrochen werden, wenn der User es nicht mehr braucht. Ctrl-C geht mir aber gegen den Strich. ;)

Gut, portabel: man könnte beide Varianten in einem Programm probieren. if windows platform, sonst gtk (vielleicht auch noch osx). Im Windows gibts doch dieses kbhit (oder getchar) von msvcrtd (falls ich mich richtig erinnert habe), das dann immer was zurückgibt. Meist halt ''. ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Francesco hat geschrieben: @BlackJack:Ich frage mich: Wie breche ich das Programm sonst elegant ab? Es soll einfach dann abgebrochen werden, wenn der User es nicht mehr braucht. Ctrl-C geht mir aber gegen den Strich. ;)
Wieso das? Ist das nicht eine durchaus übliche Kombi?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hyperion hat geschrieben:
Francesco hat geschrieben: Wieso das? Ist das nicht eine durchaus übliche Kombi?
Weil Ctrl-C ist abwürgen. Es kann ja sein, dass eine Fileoperation gerade im Gang ist. Es sollte "sanft" ausgestiegen werden. ;)

Es geht um mein Quick und Dirty Programm:
http://pastebin.com/g9QaFZa2

(das sich aus dem thread => http://www.python-forum.de/viewtopic.php?f=5&t=23753 ergeben hat)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Francesco hat geschrieben:
Hyperion hat geschrieben:
Francesco hat geschrieben: Wieso das? Ist das nicht eine durchaus übliche Kombi?
Weil Ctrl-C ist abwürgen. Es kann ja sein, dass eine Fileoperation gerade im Gang ist. Es sollte "sanft" ausgestiegen werden. ;)
Kann man das nicht mit einem KeyboardInterrupt abfangen? Oder ist das auch OS abhängig?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hyperion hat geschrieben: Kann man das nicht mit einem KeyboardInterrupt abfangen? Oder ist das auch OS abhängig?
Das würde aber genau so mittendrin aussteigen, denke ich. Ich mein so tragisch ist das bei dieser Anwendung eh nicht (wenn das letzte Bild nicht mehr richtig gespeichert wird), aber stören tuts mich schon, warum man nicht auf einen Tastendruck abfragen kann, ohne gleich wieder mit dem curses modul hantieren zu müssen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Francesco hat geschrieben:
Hyperion hat geschrieben: Kann man das nicht mit einem KeyboardInterrupt abfangen? Oder ist das auch OS abhängig?
Das würde aber genau so mittendrin aussteigen, denke ich.
Hu? Dann musst du halt im KeyboardInterrupt ein brauchbares Handling einbauen. Du kannst sogar C-c ignorieren wenn du willst. Insofern verstehe ich unter "Abwürgen" eher was anderes.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

geht das nicht über Threads? Also eine Thread, der Arbeitet und eine, der periodisch einen Tastaturbefehl abfragt...

Habe Threads selber nochnie benutzt, daher weiß ich nicht, wie abwegig mein Vorschlag ist... ;-)

Gruß, noisefloor
BlackJack

@noisefloor: Und wie fragst Du periodisch eine Taste ab? Plattformunabhängig! *Das* ist hier die Frage.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
BlackJack hat geschrieben:*Das* ist hier die Frage.
Nee, das ist eine von 2 Fragen - siehe 1. Post vom OP. :-)

Gruß, noisefloor
Zuletzt geändert von noisefloor am Samstag 14. August 2010, 20:13, insgesamt 2-mal geändert.
BlackJack

@noisefloor: Ich gebe zu das "nicht blockierend" nicht noch einmal geschrieben zu haben, aber es bleibt *eine* Frage.
Antworten