@badi113: Du musst eine Referenz auf Python-Seite auf die Bilder behalten. Wenn Du das nicht tust, dann gibt Python den Speicher für das Bild wieder frei, und Tk hat nichts zum Anzeigen.
Zu dem Code gibt's aber auch sonst noch einiges zu sagen. Das scheint auf Modulebene zu stehen – da gehört das nicht hin. Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Und man verwendet keine globalen Variablen. Alles was eine Funktion oder Methode ausser Konstanten benötigt bekommt sie als Argument(e) übergeben. Was bei jedem nicht-trivialen GUI-Programm zur Folge hat, das man objektorientierte Programmierung braucht, also selber Klassen schreiben muss.
Wenn man anfängt Namen zu nummerieren macht man in aller Regel etwas falsch. Entweder will man sich bessere Namen ausdenken, oder aber gar keine Einzelnamen sondern eine Datenstruktur verwenden. Oft eine Liste. Im Fall von `root1` ist aber der Name falsch. Es kann bei einem Baum nur *eine* Wurzel geben, und bei Tk ist das der Name für das `Tk`-Objekt. Einen `Frame` würde man einfach `frame` nennen. Eventuell mit einen Präfix der etwas über die Bedeutung des Inhalts des `Frame` aussagt, falls das interessant für den Leser sein sollte.
Das Du `Frame` einfach so benutzt lässt befürchten das aus `tkinter` einfach alles mit einem * importiert wurde. Nicht machen! Das ist Böse™. Damit holt man sich über 150 Namen ins Modul von denen nur ein Bruchteil tatsächlich benötigt wird. Und nicht nur Namen die im `tkinter`-Modul selbst definiert werden, sondern auch welche die das Modul seinerseits von woanders her importiert hat. Man hat da wenig Kontrolle was man sich da alles einfängt.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Also `dir_list` statt `dirList`. Wobei da das `list` nicht in den Namen gehört. Wenn man Grunddatentypen in Namen schreibt, bekommt man regelmässig das Problem das man während der Entwicklung den Datentyp auf einen spezialisierteren ändert, und dann entweder überall im Programm die betroffenen Namen ändern muss, oder falsche, irreführende Namen im Programm hat.
Pfadteile setzt man nicht mit ``+`` zusammen, sondern mit `os.path.join()`.
Kryptische Abkürzungen und Prä- und Suffixe sollte man vermeiden. Der Leser soll am Namen die Bedeutung des Wertes ablesen können und nicht raten müssen wöfür das `s` bei `sFile` wohl stehen mag. Wobei `file` ein guter Name für ein Dateiobjekt ist, aber ein schlechter für einen Datei*namen*. Bei `file` erwartet der Leser ein Objekt mit Methoden wie `read()`/`write()`/`close()`/… und keine Zeichenkette (oder ein `pathlib.Path`-Objekt).
Die `find()`-Methode von Sequenztypen sollte man eher nicht verwenden weil auch der Wert -1 für „nicht gefunden“ ein gültiger Index ist. Wenn man tatsächlich den Index benötigt, sollte man die `index()`-Methode nehmen. Aber der Index spielt hier ja gar keine Rolle, Du willst ja wissen ob '.gif' in dem Namen vorkommt oder nicht – dafür gibt es den ``in``-Operator: ``if '.gif' not in sFile:``. Aber halt: Das willst Du gar nicht wissen, denn '.gif' soll ja nicht *irgendwo* vorkommen, sondern am *Ende*. Das kann man mit ``if not sFile.endswith('.gif'):`` testen.
Das ist letztlich aber alles zu umständlich: es gibt das `glob`-Modul.
`icons` ist als Name wieder ungenau, denn in der Liste sind keine Icons sondern Pfade zu Icons.
So wie Du `counter` bestimmst, solltest Du noch mal ein Grundlagentutorial durcharbeiten. Das man die Anzahl von Elementen in Containertypen mit der `len()`-Funktion abfragen kann, sollte man wissen:
Code: Alles auswählen
#####Zähler für Icons in Ordner
counter = 0
for zaehler in icon_paths:
counter = counter + 1
# ->
counter = len(icon_paths)
Dann ist die ``while``-Schleife eigentlich eine ``for``-Schleife:
Code: Alles auswählen
counter = len(icon_paths)
a = 0
while a < counter:
print(icon_paths[a])
# ...
a = a + 1
# ->
for a in range(len(icon_paths)):
print(icon_paths[a])
# ...
*Das* ist in Python aber ein starkes „anti pattern“, denn `a` wird bei Dir nur als Index in die Liste verwendet. Man kann aber stattdessen *direkt* über die Elemente von Sequenzen iterieren, ohne den Umweg über einen Index:
`row` und `column` bei `grid()` als Zeichenketten anzugeben ist schräg. Warum?
Warum setzt Du bei dem `Button` direkt nach dem Erstellen Optionen, die man auch beim erstellen schon angeben kann? Wenn man das nicht machen würde, bräuchte man den `Button` nicht einmal an einen Namen binden.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import os
import tkinter as tk
from glob import glob
def main():
# ...
icon_paths = glob(os.path.join(sql_bilder, 'icons', '*.gif'))
icon_paths.sort()
icons_frame = tk.Frame(frame)
icons_frame.pack(anchor=tk.NW, fill=tk.X)
for icon_path in icon_paths:
print(icon_path)
icon_frame = tk.Frame(icons_frame)
icon_frame.pack(anchor=tk.NW, fill=tk.X)
logo = PhotoImage(file=icon_path)
icon_frame.image = logo
tk.Label(icon_frame, image=logo).grid(row=0, column=0)
tk.Button(
icon_frame, text='…', border=1, borderwidth=1, font=schrift
).grid(row=1, column=0)
# ...
if __name__ == '__main__':
main()