Python Ladebalken funktioniert nicht?
Hi,
Ich habe mit Python einen Ladebalken für ein kleines GUI erstellt. Dieser Ladebalken soll anzeigen wieviele Dateien schon Kopiert wurden. Wenn ich den Ladebalken herausnehme läuft alles. Wenn ich ihn jedoch einfüge kommen fehlermeldungen und die Dateien werden manchmal nicht korrekt Kopiert. Ich komme mitleiweile nicht mehr weiter und hoffe dass mir hier einer helfen kann.
Lg McCrafterIV
Fehlermeldung:
"C:\Users*\PycharmProjects\MakeBackup\venv\Scripts\python.exe" "C:/Users/*/PycharmProjects/MakeBackup/main.py"
Exception in Tkinter callback
ERROR! Cannot create folder.
ERROR! Cannot copy files.
ERROR! Cannot copy files.
ERROR! Cannot copy files.
Traceback (most recent call last):
File "C:\Users****\AppData\Local\Programs\Python\Python36-32\lib\tkinter__init__.py", line 1702, in __call__
return self.func(*args)
File "C:/Users//PycharmProjects/MakeBackup/main.py", line 112, in <lambda>
save_1_button = Button(fenster, text="Save", command=lambda: save.savedata())
File "C:\Users****\PycharmProjects\MakeBackup\save.py", line 40, in savedata
pb = ttk.Progressbar(fenster, orient='horizontal', length=300, mode='determinate', maximum=line, value=saved)
File "C:\Users****\AppData\Local\Programs\Python\Python36-32\lib\tkinter\ttk.py", line 1014, in __init__
Widget.__init__(self, master, "ttk::progressbar", kw)
File "C:\Users****\AppData\Local\Programs\Python\Python36-32\lib\tkinter\ttk.py", line 559, in __init__
tkinter.Widget.__init__(self, master, widgetname, kw=kw)
File "C:\Users****\AppData\Local\Programs\Python\Python36-32\lib\tkinter__init__.py", line 2296, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: expected floating-point number but got "
"
Process finished with exit code 0
Hier mein Quellcode:
https://gist.github.com/McCrafterIV/682f23b2962153beb7b640d304548dac
1 Antwort
Deine ProgressBar benutzt zwei float-Variablen namens saved und line.
Bei saved solltest Du in Zeile 35
saved += 1
schreiben.
Und line darfst Du nicht für die Textzeilen verwenden. Versuch's mal so:
with open("src.mbf", "r") as file:
lines = file.readlines()
global saved, total
saved = 0
total = len(lines)
for line in lines:
try:
copy(line.rstrip(), dest + dat)
saved += 1
except Exception ex:
print("ERROR! Cannot copy file '%s': %s"
% (line.rstrip(),ex))
pb = ttk.Progressbar(..., maximum=total, value=saved)
Außerdem schreibst Du in Zeile 19 mkdir(dest + "/" + dat), lässt den '/' beim Kopieren aber weg. So klappt es besser und spart unnötige Variablen:
with open("dst.mbf", "r", encoding='utf-8') as fdst:
dest = fdst.read() +
dt.now().strftime("/%d.%m.%Y %H-%M-%S")
try:
os.mkdir(dest)
except ex:
print("ERROR! Cannot create folder '%s': %s."
%(dest,ex))
...
copy(line.rstrip(), dest)
Noch'n Tipp: Verwende os.path.join() für dest.
Ich habe Deinen Code mal zum Laufen gebracht (es waren noch einige Fehler drin):
#!/usr/bin/env python3
import os
from time import sleep
from datetime import datetime as dt
from tkinter import *
from shutil import copy
from tkinter import ttk
import locale
def savedata():
locale.setlocale(locale.LC_ALL, '')
fenster = Tk()
ordner = StringVar()
ttk.Label(textvariable = ordner).pack()
saved = IntVar()
pb = ttk.Progressbar(fenster, length=300, variable=saved)
pb.pack()
datei = StringVar()
ttk.Label(textvariable = datei).pack()
fenster.update()
with open("dst.mbf", "r", encoding='utf-8') as fdst:
dest = fdst.read().strip() + dt.now().strftime("/%d.%m.%Y %H-%M-%S")
try:
os.mkdir(dest)
ordner.set('Kopiere nach "%s"' % dest)
except Exception as ex:
print("ERROR! Cannot create folder '%s': %s." % (dest,ex))
return
with open("src.mbf", "r") as file:
lines = file.readlines()
pb.configure(maximum = len(lines))
for line in lines:
try:
datei.set(line.rstrip())
copy(line.rstrip(), dest)
saved.set(saved.get()+1)
fenster.update()
sleep( 0.2 ) ### Pause nur zum Testen
except Exception as ex:
print("ERROR! Cannot copy file '%s': %s"
% (line.rstrip(),ex))
datei.set("%d Dateien kopiert" % saved.get())
fenster.mainloop() # Anwendung nicht beenden
if __name__ == "__main__":
savedata()
Nun habe ich noch 1 Problem...
Es kommt folgender Error:
ERROR! Cannot copy file 'C:\Users\Tim PC\AppData\Roaming\.minecraft': [Errno 13] Permission denied: 'C:\\Users\\PC\\AppData\\Roaming\\.minecraft'
Das die Datei keine berechtigung hatt kann ich selber herauslesen, schaffe jedoch nicht an die behebung des Problems. Ich habe schon probiert der Datei per cmd mehr Rechte zu geben aber dann geht es immer noch nicht...
Ist .minecraft eine normale Datei (nicht: Ordner/Systemdatei/Verknüpfung), und kannst Du sie von Hand kopieren?
copy C:\Users\Tim PC\AppData\Roaming\.minecraft nul:
Den Fall kannst Du mit os.path.isdir() abfangen und z.B. shutil.copytree() verwenden.
Gut danke. Jetz habe ich nurnoch das Problem dass der Ordner mit Datum und Uhrzeit zwar erstellt wird(und auch leer ist) aber trotzdem dieser Error kommt:
ERROR! Cannot copy file 'C:\Users\PC\AppData\Roaming\.minecraft': [WinError 183] Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist: 'E:\\minecraft/23.05.2018 14-13-33'
Bei shutil.copy() reicht es, als Ziel ein Verzeichnis anzugeben. Die Quelldatei wird dort unter gleichem Namen abgelegt.
Bei shutil.copytree() musst Du als Ziel explizit einen Namen angeben, der noch nicht existiert. Wahrscheinlich willst Du den selben Namen wie das Quellverzeichnis (hier also ".minecraft/"):
from os import path # isdir(), join()
# ...
for line in lines:
try:
line = line.rstrip()
# ...
if path.isdir(line):
copytree(line, path.join(dest,
path.basename(line)))
Danke jetzt gehts.
Allerdings noch etwas "kleines", wenn der Ordner den ich Kopieren will sehr groß ist, fängt es an zu hängen. Kennst du vielleicht ein e kleine Möglichkeit dies zu unterbinden indem jede Datei einzeln kopiert wird wenn ein Ordner kopiert wird. Was dann auch den vorteil hätte das wenn nur 1 Ordner kopiert wird das der Ladebalken nicht von 0 auf 100 springt.
Ich bin irgendwie gerade raus... :D
Vielleicht könntest du mir nochmal den gesamten Code schicken weil ich gerade einfach nicht mehr durchblicke...
Bin noch Anfänger.
Lg McCrafterIV