Fotosortierer

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
siver
User
Beiträge: 8
Registriert: Dienstag 16. Juli 2019, 09:33

Hallo zusammen,

ich bin eigentlich kein richtiger Programmierer, hab aber Spaß an der einen oder anderen Sache. Mein aktuelles Projekt beschäftigt sich mit den Fotobüchern unserer Kinder. Ich sammle alle Fotos von allen Kameras im Haushalt in einem Ordner mit der Jahreszahl. Aus dieser Ansammlung von Fotos wird jedes Jahr für jedes Kind ein Fotobuch bestellt. Dafür müssen sie vorher händisch sortiert werden. Bei 3 Kinder ein Riesenakt.
Ich versuche mich daher gerade an einer GUI mit Python Programm zu schreiben, welches alle Bilder in einem Ordner einzeln anzeigt und dann für jedes Kind eine Schaltfläche bereit hält um die Bilder in separate Ordner zu kopieren. Soweit klappt es mit dem ersten Bild. Es wir mir angezeigt und ich kann es in die Ordner kopieren. Wenn ich nun auf weiter klicke verschwindet das erste Bild und ich bekomme nur noch grauen Hintergrund zu sehen. Ich weiß aber, dass der Zeiger im Array auf das nächste Bild springt und mir diese per Knopfduck auch in die entsprechenden Ordner kopiert wird. Es wird aber nicht angezeigt. Vielleicht kann mir dabei jemand helfen.
Mir ist Bewusst, dass der Code sehr rudimentär aussieht und quasi laienhaft, aber es geht mir nur um die Funktion.
Hier der gesamte Code:

Code: Alles auswählen

from tkinter import *
import fnmatch
from PIL import Image, ImageTk
import os
from PIL import *

i=0
ordner = 'W:\\2019'
dateien = fnmatch.filter(os.listdir(ordner), '*.jpg')

def weiter(e):
    global i, ordner, dateien,label1
    i+=1
    path = ordner+"\\"+dateien[i]
    print(path)
    img = bild(path)
    label1.config(image=img)

def zurueck(e):
    global i, ordner, dateien,label1
    i-=1
    path = ordner+"\\"+dateien[i]
    print(path)
    img = bild(path)
    label1.config(image=img)

def kind1(e):
    global i, ordner, dateien

    os.system('copy '+ordner+"\\"+dateien[i]+' '+ordner+'\\Kind1\\')
    

def kind2(e):
    global i, ordner, dateien
    
    os.system('copy '+ordner+"\\"+dateien[i]+' '+ordner+'\\Kind2\\')
    

def kind3(e):
    global i, ordner, dateien
    
    os.system('copy '+ordner+"\\"+dateien[i]+' '+ordner+'\\Kind3\\')    
    

def bild(path):
    image = Image.open(path).resize((1024, 800))
    return (ImageTk.PhotoImage(image))

root=Tk()
root.title("Fotos")
root.geometry("1500x800")

path = ordner+"\\"+dateien[i]
print(path)
img = bild(path)

label1=Label(root, image=img)
label1.pack(side="left", fill = "both", expand = "yes")
button1=Button(root,height=10, width=50, text="zurück")
button1.pack(side='bottom')
button1.bind('<Button-1>',zurueck)
button2=Button(root, height=10, width=50, text="kind1")
button2.pack(side='bottom')
button2.bind('<Button-1>',kind1)
button3=Button(root, height=10, width=50, text="kind2")
button3.pack(side='bottom')
button3.bind('<Button-1>',kind2)
button4=Button(root, height=10, width=50, text="kind3")
button4.pack(side='bottom')
button4.bind('<Button-1>',kind3)
button5=Button(root, height=10, width=50, text="weiter")
button5.pack(side='bottom')
button5.bind('<Button-1>',weiter)


root.mainloop()
[/Code

Vielen Dank schon mal im Vorraus.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@siver: Das konkrete Problem liegt daran das man bei `tkinter` auf Python-Seite eine Referenz auf Bildobjeke behalten muss, sonst werden die von der Speicherbereinigung beseitigt und stehen damit auf der `Tk`-Seite nicht mehr zur Anzeige zur Verfügung. Normalerweise bindet man das Bild dafür einfach als Attribut an das Exemplar von der Klasse die man für die GUI geschrieben hat. Denn für so ziemlich jede nicht-triviale GUI braucht man objektorientierte Programmierung. Alternativ kann man das Bildobjekt auch an irgend ein anderes Objekt als Attribut zuweisen – beispielsweise an einem `Label` in dem es angezeigt wird.

An dem Quelltext ist so einiges überarbeitungswürdig.

Sternchen-Importe sind Böse™. Damit holt man sich den gesamten Inhalt eines Moduls in den Namensraum. Bei `tkinter` sind das deutlich mehr als 100(!) von denen nur ein kleiner Bruchteil verwendet wird. Nicht nur Namen die in dem Modul definiert sind, sondern auch Namen die das Modul selbst von woanders importiert. Es besteht zudem die Gefahr von Namenskollisionen. `tkinter` und `PIL` definieren beispielsweise beide eine `Image`-Klasse.

`tkinter` wird typischerweise als ``import tkinter as tk`` importiert und auf die Namen aus dem Modul dann explizit beispielsweise per `tk.Label` zugegriffen.

Der Sternchen-Import aus `PIL` macht noch nicht einmal Sinn, weil die beiden Namen die aus dem Modul verwendet werden, vorher schon explizit importiert wurden‽

Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionen und Methoden bekommen alles was sie ausser Konstanten verwenden als Argument(e) übergeben. Sie greifen nicht auf globale Variablen zu. Und verändern die schon mal gar nicht. Vergiss das es ``global`` überhaupt gibt. Zumal da sowieso nur `i` so hätte deklariert werden müssen, und das noch nicht einmal in jeder Funktion, sondern nur in `weiter()` und `zurück()`.

Das was Du mit `fnmatch.filter()` und `os.listdir()` machst, gibt es schon fertig im `glob`-Modul – mit dem zusätzlichen Vorteil, dass dabei schon komplette Pfade bei herum kommen. Alternativ kann man mal über das `pathlib`-Modul nachdenken. Auf keine Fall setzt man Pfadteile mit ``+`` zusammen. Dafür ist `os.path.join()` oder eben auch `pathlib` da.

Was soll die 1 bei `label1`? Und die ganzen durchnummerierten `button`-Namen? Wenn man Namen durchnummeriert, dann will man entweder bessere Namen verwenden oder gar keine einzelnen Namen für die Werte sondern eine Datenstruktur, meistens eine Liste. In diesem Fall sind die Namen einfach schlecht. Beim `label1` sollte man einen Namen wählen bei dem der Leser weiss *was* der Zweck von dem `Label` ist. Bei den `Button`\s ist der Name egal solange man ihn nach dem Erstellen und Anordnen nicht noch für irgend etwas braucht. Man kann natürlich trotzdem einen passenden Namen wählen, damit man die Stelle wo ein `Button` für einen bestimmten Zweck erstellt wird, leichter finden kann.

`bind()` ist der falsche Weg im Aktionen an `Button`\s zu binden. Die haben dafür das `command`-Argument, und nur dann verhält sich die Schaltfläche so wie der Benutzer das erwartet und von anderen Schaltflächen gewohnt ist.

Funktions- und Methodennamen reflektieren üblicherweise die Tätigkeit, die sie durchführen. Keiner der Funktionsnamen tut das tatsächlich.

Statt `bild()` nur zum Laden zu verwenden, sollte da auch gleich die GUI aktualisiert werden, denn den Code hast Du momentan drei mal im Code stehen, jeweils nach dem laden.

`os.system()` sollte man nicht verwenden, das steht auch in der Dokumentation. Zum Kopieren von Dateien ist es aber auch gar nicht notwendig ein externes Programm aufzurufen. Entsprechende Funktionen findet man im `shutil`-Modul in der Standardbibliothek.

Die drei `kind*()`-Funktionen machen im Grunde das selbe, das sollte nur eine Funktion sein, mit dem Zielordner als Argument.

Ungetesteter Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
from functools import partial
import glob
import os
import shutil
import tkinter as tk

from PIL import Image, ImageTk

ORDNER = 'W:\\2019'

# 
# TODO Eine Klasse für die GUI schreiben und Schaltflächen die aktuell nichts
#   bewirken können, deaktivieren.
# 

def show_next_image(dateinamen, dateinamenindex_var, image_label):
    # 
    # FIXME Index kann grösser werden als Anzahl der Dateinamen.
    # 
    dateinamenindex_var.set(dateinamenindex_var.get() + 1)
    update_image_label(dateinamen, dateinamenindex_var, image_label)


def show_previous_image(dateinamen, dateinamenindex_var, image_label):
    # 
    # FIXME Index kann kleiner werden als Anzahl der Dateinamen.
    # 
    dateinamenindex_var.set(dateinamenindex_var.get() - 1)
    update_image_label(dateinamen, dateinamenindex_var, image_label)


def copy_file(dateinamen, dateinamenindex_var, target):
    shutil.copy2(
        dateinamen[dateinamenindex_var.get()], os.path.join(ORDNER, target)
    )


def update_image_label(dateinamen, dateinamenindex_var, image_label):
    image = ImageTk.PhotoImage(
        Image.open(dateinamen[dateinamenindex_var.get()]).resize((1024, 800))
    )
    image_label.image = image
    image_label['image'] = image


def main():
    root = tk.Tk()
    root.title('Fotos')
    root.geometry('1500x800')

    image_label = tk.Label(root)
    image_label.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    
    dateinamenindex_var = tk.IntVar(value=0)
    dateinamen = glob.glob(os.path.join(ORDNER, '*.jpg'))
    update_image_label(dateinamen, dateinamenindex_var, image_label)

    previous_button = tk.Button(
        root,
        height=10,
        width=50,
        text='zurück',
        command=partial(
            show_previous_image, dateinamen, dateinamenindex_var, image_label
        ),
    )
    previous_button.pack(side=tk.BOTTOM)
    
    for i in range(1, 4):
        tk.Button(
            root,
            height=10,
            width=50,
            text=f'kind{i}',
            command=partial(
                copy_file, dateinamen, dateinamenindex_var, f'Kind{i}'
            ),
        ).pack(side=tk.BOTTOM)
    
    next_button = tk.Button(
        root,
        height=10,
        width=50,
        text='weiter',
        command=partial(
            show_next_image, dateinamen, dateinamenindex_var, image_label
        ),
    )
    next_button.pack(side=tk.BOTTOM)
    
    root.mainloop()


if __name__ == '__main__':
    main()
Bei den Vor-/Zurück-Schaltflächen wird der Index verändert ohne zu prüfen ob der noch innerhalb der Grenzen liegt. Benutzerfreundlich wäre zudem wenn man eine Schaltfläche deaktiviert wenn sie keine sinnvolle Aktion durchführen kann (`state`-Option von Widgets und `tk.DISABLED` und `tk.NORMAL`). Das aber erst nach dem eine Klasse für die GUI existiert, denn hier kommt `partial()` an die Grenzen eines sinnvollen Einsatzes.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
siver
User
Beiträge: 8
Registriert: Dienstag 16. Juli 2019, 09:33

Ich danke dir für deinen Beitrag. Ich hab mir das aus mehreren Seiten und Foren zusammen gebastelt. Die Fehler, die ich gemacht habe, habe ich von diesen Seiten. Daher bin ich sehr Dankbar, wenn ich Ratschläge bekomme, wie es richtig gemacht wird.

Wenn ich programmiere, dann nahezu ausschließlich prozedural. Objektorientiert bin ich noch nicht so richtig durchgestiegen. Daher werde ich eine Weile brauchen bis ich den Code verstanden habe. Derzeit bekomme ich auf Zeile 41 "Image.open(dateinamen[dateinamenindex_var.get()]).resize((1024, 800))
IndexError: list index out of range"

Ich werde versuchen da durch zu steigen. Vielen Dank für deine Hilfe.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@siver: Um *den* Code zu verstehen braucht's noch keine Objektorientierung, denn da ist ja noch gar keine. Das ist prozedural mit ein bisschen funktionaler Programmierung.

Wenn Du den `IndexError` sofort beim starten bekommst, dann wurden keine passenden Dateinamen gefunden. Das Problem hätte Dein Code aber auch gehabt in diesem Fall. Den müsste man dann auch noch im Code berücksichtigen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
siver
User
Beiträge: 8
Registriert: Dienstag 16. Juli 2019, 09:33

Ich scheine es tatsächlich langsam zu verstehen. Und ja es funktioniert. Es lag einfach daran, dass das Netzlaufwerk noch nicht verbunden war. Hätte ich auch selber drauf kommen müssen...
Das zeigt mir, was für ein blutiger Anfänger ich noch bin :shock:
Ich verneige mich vor dir. Irgendwann kann ich das hoffentlich auch mal so. Vielen Dank.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ganze mit einer Klasse:

Code: Alles auswählen

#!/usr/bin/env python3
from functools import partial
import shutil
import tkinter as tk
from pathlib import Path
from PIL import Image, ImageTk

ORDNER = Path('W:\\2019')

class ImageView:
    def __init__(self, root):
        self.image_label = tk.Label(root)
        self.image_label.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    
        self.previous_button = tk.Button(
            root,
            height=10,
            width=50,
            text='zurück',
            state=tk.DISABLED
            command=partial(self.switch_image, -1),
        )
        self.previous_button.pack(side=tk.BOTTOM)
    
        for i in range(1, 4):
            tk.Button(
                root,
                height=10,
                width=50,
                text=f'Kind{i}',
                command=partial(self.copy_file, ORDNER / f'Kind{i}'),
            ).pack(side=tk.BOTTOM)
        
        self.next_button = tk.Button(
            root,
            height=10,
            width=50,
            text='weiter',
            command=partial(self.switch_image, 1),
        )
        self.next_button.pack(side=tk.BOTTOM)

        self.dateinamenindex = 0
        self.dateinamen = list(ORDNER.glob('*.jpg'))
        self.update_image_label()

    def switch_image(self, direction):
        self.dateinamenindex += direction
        self.previous_button['state'] = tk.DISABLED if self.dateinamenindex <= 0 else tk.NORMAL
        self.next_button['state'] = tk.DISABLED if self.dateinamenindex >= len(self.dateinamen) - 1 else tk.NORMAL
        self.update_image_label()

    def copy_file(self, target):
        dateiname = self.dateinamen[self.dateinamenindex]
        shutil.copy2(dateiname, target)

    def update_image_label(self):
        dateiname = self.dateinamen[self.dateinamenindex]
        image = ImageTk.PhotoImage(
            Image.open(dateiname).resize((1024, 800))
        )
        self.image_label.image = image
        self.image_label['image'] = image


def main():
    root = tk.Tk()
    root.title('Fotos')
    root.geometry('1500x800')
    image_view = ImageView(root)    
    root.mainloop()


if __name__ == '__main__':
    main()
siver
User
Beiträge: 8
Registriert: Dienstag 16. Juli 2019, 09:33

Ich hab noch ein wenig an der prozeduralen rumgebastelt. Eventuell taste ich mich noch an die objektorientierte Version ran. Das mit den ausgegrauten Buttons hab ich noch nicht umgesetzt. Weil mein Frau dieses Programm bedienen soll, habe ich einige Anweisungen drin um Fehler, wie fehlende Ordner und doppelte Dateien zu vermeiden. Des Weiteren sind die Fotos nun nach Dateinamen sortiert.

Und was auch ein kleiner Knackpunkt war, die Bilder werde jetzt nicht mehr verzehrt dargestellt und passen immer in die vorgegebene Fenstergröße.

Code: Alles auswählen

#!/usr/bin/env python3
from functools import partial
from pathlib import Path
import fnmatch
import os
import shutil
import tkinter as tk

from PIL import Image, ImageTk, ExifTags

ORDNER = 'W:\\2018'


def show_next_image(dateinamen, dateinamenindex_var, image_label, data_label):

    dateinamenindex_var.set(dateinamenindex_var.get() + 1)
    update_image_label(dateinamen, dateinamenindex_var, image_label, data_label)


def show_previous_image(dateinamen, dateinamenindex_var, image_label, data_label):

    dateinamenindex_var.set(dateinamenindex_var.get() - 1)
    update_image_label(dateinamen, dateinamenindex_var, image_label, data_label)


def copy_file(dateinamen, dateinamenindex_var, target, data_label):
    if not os.path.exists(os.path.join(ORDNER, target)):
        os.makedirs(os.path.join(ORDNER, target))
    file = Path(os.path.join(ORDNER,target,dateinamen[dateinamenindex_var.get()]))
    
    if(file.is_file()):
        data_label['text'] = 'Bild: {} Datei: {} Bild breits in {} vorhanden'.format(dateinamenindex_var.get()+1,dateinamen[dateinamenindex_var.get()],target)
    else:
        shutil.copy2(os.path.join(ORDNER,dateinamen[dateinamenindex_var.get()]), os.path.join(ORDNER, target))
        data_label['text'] = 'Bild: {} Datei: {} Bild wurde zu {} kopiert'.format(dateinamenindex_var.get()+1,dateinamen[dateinamenindex_var.get()],target)

def update_image_label(dateinamen, dateinamenindex_var, image_label, data_label):
    tmp = Image.open(os.path.join(ORDNER,dateinamen[dateinamenindex_var.get()]))
    exif = {
        ExifTags.TAGS[k]: v
        for k, v in tmp._getexif().items()
        if k in ExifTags.TAGS
    }
    print (exif)
    max_breite = 1024
    max_hoehe = 800
    neue_breite = int(exif['ExifImageWidth']*max_hoehe/exif['ExifImageHeight'])
    if(neue_breite > max_breite):
        neue_hoehe = int(exif['ExifImageHeight']*max_breite/exif['ExifImageWidth'])
        neue_breite = max_breite
    else:
        neue_hoehe = max_hoehe

    image = ImageTk.PhotoImage(tmp.resize((neue_breite, neue_hoehe)))
    data_label.text = dateinamen[dateinamenindex_var.get()]
    data_label['text'] = 'Bild: {} Datei: {}'.format(dateinamenindex_var.get()+1,dateinamen[dateinamenindex_var.get()])
    image_label.image = image
    image_label['image'] = image


def main():
    root = tk.Tk()
    root.title('Fotos')
    root.geometry('1500x800')

    data_label = tk.Label(root)
    data_label.pack()
        
    image_label = tk.Label(root)
    image_label.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    
    dateinamenindex_var = tk.IntVar(value=0)
    dateinamen = fnmatch.filter(os.listdir(ORDNER), '*.jpg')
    dateinamen.sort()
    

    previous_button = tk.Button(
        root,
        height=10,
        width=50,
        text='zurück',
        command=partial(
            show_previous_image, dateinamen, dateinamenindex_var, image_label, data_label
        ),
    )
    previous_button.pack(side=tk.BOTTOM)

    namen = ["Emil", "Frieda", "Luise"]
    
    for i in namen:
        tk.Button(
            root,
            height=10,
            width=50,
            text=i,
            command=partial(
                copy_file, dateinamen, dateinamenindex_var, i, data_label
            ),
        ).pack(side=tk.BOTTOM)
    
    next_button = tk.Button(
        root,
        height=10,
        width=50,
        text='weiter',
        command=partial(
            show_next_image, dateinamen, dateinamenindex_var, image_label, data_label
        ),
    )
    next_button.pack(side=tk.BOTTOM)

    update_image_label(dateinamen, dateinamenindex_var, image_label, data_label)
    
    root.mainloop()


if __name__ == '__main__':
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@siver: `pathlib` wird eher subobtimal verwendet. Entweder die Funktionen aus `os.path` *oder* `pathlib` – aber beides mischen, und dann auch noch innerhalb einer Funktion ist eher verwirrend.

`os.makedirs()` kann man sagen, dass es Okay ist, wenn der Zielpfad schon existiert – da braucht man nicht vorher zu prüfen ob es den schon gibt.

In `copy_file()` wird dreimal `ORDNDER` und `target` zusammengesetzt, statt den Code dafür *einmal* zu schreiben, und das Ergebnis an einen Namen zu binden. Da kommt doch bei jedem Aufruf das gleiche heraus.

Der Ausdruck ``dateinamen[dateinamenindex_var.get()]`` steht da auch dreimal, auch den würde ich nur einmal schreiben wollen.

Der Text der dort in das Label gesetzt wird, verwendet die gleichen Daten für die Platzhalter – es unterscheidet sich also eigentlich nur die Vorlage.

``if`` ist keine Funktion – da gehören keine Klammern um die Bedingung und ein Leerzeichen zwischen das Schlüsselwort und die Bedingung.

Ungetestet – ohne `os` und `fnmatch`, nur mit `Path`:

Code: Alles auswählen

ORDNER = Path('W:\\2018')

# ...

def copy_file(dateinamen, dateinamenindex_var, target, data_label):
    source_path = dateinamen[dateinamenindex_var.get()]
    target_directory = ORDNER / target
    target_directory.mkdir(parents=True, exist_ok=True)
    target_path = target_directory / source_path.name
    
    if target_path.is_file():
        text_template = 'Bild: {} Datei: {} Bild breits in {} vorhanden'
    else:
        shutil.copy2(source_path, target_path)
        text_template = 'Bild: {} Datei: {} Bild wurde zu {} kopiert'
    
    data_label['text'] = text_template.format(
        dateinamenindex_var.get() + 1, source_path.name, target
    )

# ...

def main():
    # ...
    dateinamen = sorted(ORDNER.glob('*.jpg'))
    # ...
Wenn ich mehr als drei Namen per `partial()` binde, ist für mich in der Regel der Punkt erreicht wo ich auf eine Klasse umsteigen will.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
siver
User
Beiträge: 8
Registriert: Dienstag 16. Juli 2019, 09:33

vielen Dank für deine Beiträge.

Ich drehe nun das Bild entsprechend seiner Ausrichtung und hab eine Löschfunktion hinzugefügt.

Code: Alles auswählen

#...

def delete_image(dateinamen, dateinamenindex_var, image_label, data_label):
    messagebox.askokcancel("löschen", "Möchtest du wirklich die Datei {} löschen?".format(dateinamen[dateinamenindex_var.get()]), icon='warning')
    if 'yes':
        os.remove(os.path.join(ORDNER,dateinamen[dateinamenindex_var.get()]))
        dateinamen.remove(dateinamen[dateinamenindex_var.get()])
        update_image_label(dateinamen, dateinamenindex_var, image_label, data_label)

#...

def update_image_label(dateinamen, dateinamenindex_var, image_label, data_label):
    tmp = Image.open(os.path.join(ORDNER,dateinamen[dateinamenindex_var.get()]))
    exif = {
        ExifTags.TAGS[k]: v
        for k, v in tmp._getexif().items()
        if k in ExifTags.TAGS
    }
    print (exif['Orientation'])

    if exif['Orientation']==6:
       grad = 270
       max_breite = 800
       max_hoehe = 1024
    elif exif['Orientation']==):
       grad = 90
       max_breite = 800
       max_hoehe = 1024
    else:
       grad = 0
       max_breite = 1024
       max_hoehe = 800         
    

    neue_breite = int(exif['ExifImageWidth']*max_hoehe/exif['ExifImageHeight'])
    if neue_breite > max_breite:
        neue_hoehe = int(exif['ExifImageHeight']*max_breite/exif['ExifImageWidth'])
        neue_breite = max_breite
    else:
        neue_hoehe = max_hoehe
        
    image = ImageTk.PhotoImage(tmp.resize((neue_breite, neue_hoehe)).rotate(grad))
    data_label.text = dateinamen[dateinamenindex_var.get()]
    data_label['text'] = 'Bild: {} Datei: {}'.format(dateinamenindex_var.get()+1,dateinamen[dateinamenindex_var.get()])
    image_label.image = image
    image_label['image'] = image

#...


    delete_button = tk.Button(
        root,
        height=8,
        width=50,
        text='löschen',
        command=partial(
            delete_image, dateinamen, dateinamenindex_var, image_label, data_label
        ),
    )
    delete_button.pack(side=tk.BOTTOM)

#...

Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

`dateinamen.remove()` ist etwas umständlich wenn man den Index ja bereits hat. Dann ist `pop()` effizienter. Und Du kümmerst Dich glaube ich immer noch nicht um den Fall das die Liste leer ist oder wird. Kann beim Löschen von Bildern ja auch passieren.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Ein `if 'yes':` ist immer wahr, weil jeder nicht-leere String wahr ist.
Du hast immer noch viel doppelten Code. `dateinamenindex_var` könnte außerhalb des Indexes sein, wenn Du das letzte Bild löschst. Ein `remove` ist ziemlich umständlich, wenn Du doch schon den Index des Eintrags kennst.

Code: Alles auswählen

def delete_image(dateinamen, dateinamenindex_var, image_label, data_label):
    dateiname = dateinamen[dateinamenindex_var.get()]
    ok = messagebox.askokcancel("löschen", f"Möchtest du wirklich die Datei {dateiname} löschen?", icon='warning')
    if ok:
        os.remove(os.path.join(ORDNER, dateiname))
        del dateinamen[dateinamenindex_var.get()]
        # TODO: eventuell dateinameindex_var anpassen
        update_image_label(dateinamen, dateinamenindex_var, image_label, data_label)
siver
User
Beiträge: 8
Registriert: Dienstag 16. Juli 2019, 09:33

Ich finde es fantastisch wir ihr mir helft. Ich nehme an, ihr seid Anwendungsentwickler, oder macht ihr das Hobbymäßig? Ich komme leider heute und Morgen nicht dazu was zu ändern. Aber ich bleibe auf jeden Fall dran. Mein Dank ist euch aber sicher.
Antworten