Ich habe eine Anwendung, von der eine Datei von src
nach dst
kopiert wird:
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?
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:
und vergleichen Sie die copied
size mit der Dateigröße.
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.
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:
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.
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:
Das könnte ein bisschen hacky sein, aber es funktioniert:
%Vor%Tags und Links python multithreading