Holen Sie den Fortschritt aus dem Shutfile-Copy-Thread zurück

8

Ich habe eine Anwendung, von der eine Datei von src nach dst kopiert wird:

%Vor%

Ich möchte, dass die Anwendung den Fortschritt der Kopie alle 5 Sekunden abfragt, ohne die Anwendung selbst zu sperren. Ist das möglich?

Ich möchte diesen Fortschritt auf einen QtGui.QLabel setzen, um dem Benutzer eine Rückmeldung über die Dateikopie zu geben.

Kann dies erreicht werden, wenn mit einer Shutfile-Datei kopiert wird?

    
fredrik 30.04.2015, 12:13
quelle

5 Antworten

12

shutil.copy() bietet keine Optionen zum Verfolgen des Fortschritts, nein. Sie können höchstens die Größe der Zieldatei überwachen (indem Sie os.* functions für den Zieldateinamen verwenden).

Die Alternative wäre, eine eigene Kopierfunktion zu implementieren. Die Implementierung ist wirklich ziemlich einfach; shutil.copy() ist im Grunde ein shutil.copyfile() plus shutil.copymode() Anruf; shutil.copyfile() wiederum delegiert die eigentliche Arbeit an shutil.copyfileobj() (Links zu der Python-Quellcode).

Die Implementierung Ihres eigenen shutil.copyfileobj() zur Einbeziehung des Fortschritts sollte trivial sein; inject Unterstützung für eine Callback-Funktion, um jedes Mal, wenn ein anderer Block kopiert hat, das Programm zu informieren:

%Vor%

und vergleichen Sie die copied size mit der Dateigröße.

    
Martijn Pieters 30.04.2015, 12:24
quelle
1

Ich habe Martijn Pieters mit einem Fortschrittsbalkencode von diese Antwort mit Änderungen in PyCharm arbeiten von diese Antwort , die mir folgendes gibt. Die Funktion copy_with_progress war mein Ziel.

%Vor%     
flutefreak7 25.01.2018 19:15
quelle
0

Nein, das kann nicht so gemacht werden, weil shutil.copy keine Möglichkeit hat, Fortschritte zu erzielen.

Aber Sie können Ihre eigene Kopierfunktion schreiben (oder sogar den Code aus shutil - Beachten Sie, dass es sich um eines der Module handelt, das oben einen Link zu der Quelle enthält Das bedeutet, dass es für Beispielcode genauso nützlich sein soll wie für die Verwendung von as-is. Ihre Funktion kann z. B. eine Fortschrittsrückruffunktion als zusätzliches Argument annehmen und sie nach jedem Puffer (oder jedem N Puffer oder jedem N Byte oder jedem N Sekunden) aufrufen. Etwas wie:

%Vor%

Nun wird dieser Callback immer noch im Hintergrundthread und nicht im Hauptthread aufgerufen. Bei den meisten GUI-Frameworks bedeutet dies, dass GUI-Widgets nicht direkt berührt werden können. Aber die meisten GUI-Frameworks haben die Möglichkeit, eine Nachricht von einem Hintergrundthread an die Ereignisschleife des Hauptthreads zu senden, also machen Sie das Callback einfach. Mit Qt machen Sie das mit Signalen und Slots, genauso wie Sie es im Hauptthread tun; Es gibt viele großartige Tutorials, wenn Sie nicht wissen, wie.

Alternativ könntest du es so machen, wie du es vorgeschlagen hast: den Haupt-Thread den Hintergrund-Thread signalisieren lassen (zB indem du auf queue.Queue oder Event oder Condition trägst) und deine copy -Funktion hast Überprüfen Sie dieses Signal jedes Mal durch die Schleife und reagieren Sie. Aber das scheint sowohl komplizierter als auch weniger ansprechend zu sein.

Noch eine Sache: Qt hat eine eigene Threading-Bibliothek, und Sie möchten sie vielleicht anstelle von Pythons nativer verwenden, da Sie einen Slot direkt an QThread -Objekt anhängen können und diesen zu Ihrem Callback machen können. Ich bin mir nicht sicher, aber Qt könnte sogar irgendwo eine eigene Datei-Copy-with-Progress-Methode haben; Sie versuchen, alles einzupacken, das zwischen Plattformen und vage mit GUIs verwandt sein könnte.

    
abarnert 30.04.2015 12:20
quelle
0

Zusätzlich zu Martijn Pieters ausgezeichnete Antwort, wenn (wie ich, Ich bin ein Idiot ) Sie müssen herausfinden, wie Sie den eigentlichen Callback an die copyfileobj() -Funktion übergeben, Sie können es so machen:

%Vor%     
Dhiraj Gupta 24.08.2017 15:36
quelle
0

Das könnte ein bisschen hacky sein, aber es funktioniert:

%Vor%     
ali jafargholi 06.04.2018 03:31
quelle

Tags und Links