@coethen25: Einige Zeile sind durch Kommentare am Zeilenende viel zu lang. Früher war die Längenempfehlung 80 Zeichen pro Zeile. Das ist mittlerweile bei 120, aber ich würde trotzdem bei 80 bleiben, denn es gibt noch genug Stellen wo Code angeschaut werden kann die sich an dieser traditionellen Terminalbreite orientieren und wo es schwer lesbar wird wenn Code länger ist und dann umgebrochen wird oder nicht mehr vollständig sichtbar ist.
Die Kommentare bei den Funktionen würden sich auch eher als Docstrings eignen.
Es wird mal 'end' als Zeichenkette verwendet und mal die Konstante `tk.END`.
Beim erstellen des neuen Dateinamens mit `index()` die Position in der Liste zu ermitteln ist ineffizient. Die fortlaufende Zahl erstellt man am besten mit `enumerate()`.
„Fotos ändern“ und „speichern“ ist fast identisch, bis auf die Art wie das Zielverzeichnis ermittelt wird. Das kann man in einer Funktion zusammen fassen. Bein einer Aktion wird der Benutzer gezwungen einen neuen Namen einzugeben, bei der anderen nicht, obwohl beide den Namen benötigen. Die Ausgaben für den Benutzer sind unterschiedlich, obwohl die Aktionen fast identisch sind.
Schaltflächen in ein `Label` zu stecken ist eher ungewöhnlich. Dazu sind `Frame`\s vorgesehen.
Wie schon im letzten Beitrag: Einbuchstabige und einbuchstabige durchnummerierte Namen sind schlecht.
Man sollte sowohl Code als auch Datenwiederholungen vermeiden. Wenn alle Schaltflächen den gleichen Satz an Argumenten beim erstellen bekommen, sollte man die nur *einmal* schreiben und nicht immer und immer wieder. Das bläht den Quelltext unnötig auf und macht es schwieriger Änderungen an diesen Daten vorzunehmen die für viele Anzeigeelemente gelten.
Die `destroy()`-Methode ist ziemlich hart wenn man eigentlich einfach nur die GUI-Hauptschleife verlassen möchte. Dafür ist die `quit()`-Methode da.
Ich lande als Zwischenergebnis ungefähr bei so etwas (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3.5
# coding: utf-8
import os
import shutil
from functools import partial
import tkinter as tk
from tkinter.filedialog import askdirectory, askopenfilenames
from tkinter.messagebox import showwarning
def rename_and_copy(filenames, new_basename, destination_path=None):
for i, filename in enumerate(filenames):
new_filename = '{0}{1}{2}'.format(
new_basename, i, os.path.splitext(filename)[1]
)
destination = os.path.join(
destination_path if destination_path else os.path.dirname(filename),
new_filename
)
shutil.copy(filename, destination)
yield new_filename
class FotoRename(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, bg='#ccc', bd=2, relief=tk.GROOVE)
self.filenames = set()
button_options = {
'background': '#8b0000',
'foreground': '#ffffaa',
'activebackground': '#ffffaa',
'activeforeground': '#8b0000',
}
button_frame_background = '#8b8b8b'
text_options = {'width': 60, 'height': 7, 'background': '#fafafa'}
frame = tk.Frame(self, background=button_frame_background)
frame.pack(fill=tk.X)
tk.Button(
frame,
text='Fotos öffnen',
command=self.add_filenames,
**button_options
).pack(side=tk.LEFT, padx=7)
tk.Button(
frame,
text='Fotos ändern',
command=partial(self.copy_and_rename, False),
**button_options
).pack(side=tk.LEFT, padx=7)
tk.Button(
frame, text='Reset', command=self.reset, **button_options
).pack(side=tk.RIGHT, padx=7)
frame_options = {'background': '#ccc', 'border': 2, 'relief': tk.GROOVE}
frame = tk.Frame(self, **frame_options)
frame.pack()
self.originals = tk.Text(frame, **text_options)
self.originals.pack()
frame = tk.Frame(self, **frame_options)
frame.pack()
tk.Label(
frame, bg='#ccc', text='Bitte neuen Namen eingeben:'
).pack(side=tk.LEFT, padx=11)
self.new_name = tk.Entry(frame, width=24, font='Helvetia 10')
self.new_name.pack(side=tk.RIGHT, padx=10)
frame = tk.Frame(self, **frame_options)
frame.pack()
self.modified = tk.Text(frame, **text_options)
self.modified.pack()
frame_options['background'] = button_frame_background
frame = tk.Frame(self, **frame_options)
frame.pack(fill=tk.X)
tk.Button(
frame, text='schliessen', command=self.quit, **button_options
).pack(side=tk.RIGHT, padx=10)
tk.Button(
frame,
text='speichern',
command=partial(self.copy_and_rename, True),
**button_options
).pack(side=tk.LEFT, padx=10)
def add_filenames(self):
self.filenames.update(askopenfilenames())
self.originals.delete(1.0, tk.END)
self.originals.insert(1.0, ', '.join(sorted(self.filenames)))
self.originals.yview(tk.END)
def copy_and_rename(self, ask_for_destination):
new_name = self.new_name.get()
if not new_name:
showwarning(
'Achtung',
'Bitte erst einen Namen eingeben\n'
'(ohne Dateiendung z.B. bild_ )'
)
else:
destination_path = askdirectory() if ask_for_destination else None
self.modified.delete(1.0, tk.END)
self.modified.insert(
1.0,
', '.join(
rename_and_copy(
sorted(self.filenames), new_name, destination_path
)
)
)
self.modified.yview(tk.END)
def reset(self):
self.filenames = set()
self.originals.delete(1.0, tk.END)
self.modified.delete(1.0, tk.END)
def main():
root = tk.Tk()
root.title('Fotos umbenennen')
main_ui = FotoRename(root)
main_ui.pack(fill=tk.X)
root.mainloop()
if __name__ == '__main__':
main()