2017-01-22 1 views
0

Ich versuche, die getch und progressbar Python-Module unter Linux zu kombinieren, aber ich kann es nicht zum Laufen bringen. Ich möchte getch verwenden, um auf Tastatureingaben zu warten, um den Fortschrittsbalken zu unterbrechen, aber wenn ich die getch-Anweisung einfüge, verweigert der Fortschrittsbalken die automatische Aktualisierung, nur wenn ich eine Taste auf der Tastatur drücke.Getch und progressbar

Der Code, den ich derzeit verwende, ist unten. Ich benutze ProgressBar2 und das getch-Modul, aber ich habe versucht, tqdm und meine eigene getch-Methode ohne Erfolg zu verwenden.

bar = progressbar.ProgressBar() 
for i in range(101): 
    sleep(0.01) 
    bar.update(i) 
    ch = getch.getch() 

Als meine eigene Implementierung von getch verwenden, ich habe das Problem eingrenzen mit der ‚sys.stdin.read (1)‘ Zeile in dem folgenden Code zu sein.

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

Unter Windows, mit dem msvcrt-Modul, habe ich keinerlei Probleme.

+0

Ich würde 'file.read()' Blöcke standardmäßig annehmen. Wie wäre es mit [urwid] (http://urwid.org/), die eine Ereignisschleife, Tastaturereignisse, ein Fortschrittsbalken-Widget (unter anderem) hat? – blubberdiblub

Antwort

0

Ich hatte das gleiche Problem unter Linux, also entschied ich mich für eine andere Lösung: Capture das Signal SIGINT (STRG + C), um elegant zu beenden, oder sofort nach zwei Drücken (der normale SIGINT Weg).

import signal 
import time 

signal.signal(signal.SIGINT, signal_handler) 
sigint_again = False 
asked_termination = False 

def signal_handler(self, signal, frame): 
    """Handles SIGINT signal, blocks it to terminate gracefully""" 
    print('You pressed Ctrl+C!:', signal, frame) 
    if is_sigint_called_twice(): 
     print("\nForced terminating script!") 
     sys.exit(0) 
    asked_termination = True 

def is_sigint_called_twice(self): 
    """Check if pressing ctrl+c a second time to terminate immediately""" 
    if not sigint_again: 
     sigint_again = True 
     return False 
    else: 
     return True 

while not asked_termination: 
    print("do_stuff()") 
    time.sleep(1)