0

Ziel meines Codes ist es, über tkinter einen Fortschrittsbalken zu erzeugen, und während ich Fortschritte mit meinem Fortschrittsbalken mache, möchte ich eine .7z-Datei über Subprozess aufrufen 7 -Postleitzahl.Führen Sie asynchrone Tasks über Subprozess ohne Thread-Blockierung aus.

Nach dem Extrahieren der 7-Zip-Dateien möchte ich den Computer herunterfahren. Das erste Problem dabei ist, dass die Codezeile nach der Zeile, die die 7-Zip-Dateien extrahiert, den Computer ausführt und herunterfährt, ohne zu warten.

In Anbetracht dessen muss ich warten, bis die Extraktion beendet ist, bevor Sie fortfahren. Ein Catch-22 damit ist, dass ich keinen meiner Threads blockieren kann, weil ich meinen Fortschrittsbalken immer noch laufen lasse. Mit meinem aktuellen Code kann ich auf die Extraktion warten, aber der Fortschrittsbalken wird erst angezeigt, wenn die Extraktion beendet ist, da alle Threads blockiert sind.

Asynchron gesprochen, in gewisser Weise, wie kann ich mein Ziel erreichen?

Hier ist meine Fortschritte Strichcode:

class FinishSetup(tk.Toplevel): 

    # progress bar to simulate finishing set up 
    def __init__(self, *args, **kwargs): 
     tk.Toplevel.__init__(self, *args, **kwargs) 
     self.progress = ttk.Progressbar(self, orient="horizontal", 
      length=200, mode="determinate") 
     self.progress.pack() 

     self.bytes = 0 
     self.maxbytes = 0 

     self.size_top() 

    def start(self): 
     self.progress["value"] = 0 
     self.maxbytes = 100000 
     self.progress["maximum"] = 100000 
     self.read_bytes() 

    def read_bytes(self): 
     self.bytes += 100 
     self.progress["value"] = self.bytes 
     if self.bytes < self.maxbytes: 
      # read more bytes after 100 ms 
      self.after(100, self.read_bytes) 

    def size_top(self): 
     self.resizable(width=False, height=False) 

     ws = self.winfo_screenwidth() 
     hs = self.winfo_screenheight() 

     w = 200 
     h = 22 

     x = (ws/2) - (w/2) 
     y = (hs/2) - (h/2) 

     self.geometry('%dx%d+%d+%d' % (w, h, x, y)) 

     self.protocol("WM_DELETE_WINDOW", self.iconify) 
     self.lift() 
     self.attributes('-topmost', 'true') 
     self.overrideredirect(True) 

Und mein Haupt-Code, der die 7-Zip-Dateien extrahiert:

archive_name = 'files.7z' 
maps_dir = 'output' 

extract = subprocess.Popen('"C:\\Program Files\\7-Zip\\7z.exe" x ' + archive_name + ' -o' + maps_dir, stdout=subprocess.PIPE) 

for line in iter(extract.stdout.readline,''): 
    print(line.rstrip()) 

print('Finished') 

Ich muss in der Lage, mein Fortschrittsbalken FinishSetup().start(), laufen während Extrahieren meine 7-Zip-Dateien, und nach diesem Schritt, meinen Computer herunterfahren.

Ich habe versucht, dies für einen ganzen Tag richtig zu machen, aber ich bin zu der Erkenntnis getrieben, dass dies einfach nicht möglich ist.

Bitte lassen Sie mich Ihre Gedanken wissen, und wenn es noch etwas gibt, sollte ich versuchen.

+0

Dies sollte möglich sein, aber was Sie berücksichtigen müssen, ist, dass tkinter * mit Multithreading in einer Anwendung * nicht nett spielt. Es ist nicht so, dass es unmöglich ist, es wird einfach kein Spaß für dich sein, es zu programmieren, gottverdächtige tapfere Seele. –

Antwort

0

Die Lösung besteht darin, die Extraktion in einem separaten Thread oder Prozess durchzuführen. Dieser zweite Thread oder Prozess kann über eine Warteschlange mit der GUI kommunizieren. Sie können die Warteschlange auf der GUI-Seite abfragen, indem Sie after verwenden, um ständig eine Funktion neu zu planen, die die Warteschlange alle paar hundert Millisekunden überprüft.

Verwandte Themen