@SkyEnd: Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 140 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Man verwendet keine globalen Variablen. Alles was eine Funktion oder Methode ausser Konstanten benötigt, sollte als Argument(e) übergeben werden. Bei jeder nicht-trivialen GUI kommt man deshalb nicht um objektorientierte Programmierung (OOP) herum. Also eigene Klassen schreiben.
Beim Kommentar ``# creat GUI interface`` fehlt ein "e" bei "create" und das "interface" ist zu viel, denn das "I" in "GUI" steht ja schon für "interface". Aber letztlich kann man sich den Kommentar auch komplett schreiben, denn das sieht man ja am Code was da passiert.
Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Man nummeriert keine Namen. Man will sich dann entweder sinnvolle Namen überlegen, oder gar keine Einzelnamen und -werte verwenden, sondern eine Datenstruktur. Oft eine Liste. Bei `bg1` bis `bg6` ganz offensichtlich eine Liste, denn da landen die Werte letztlich. Warum vorher an nummerierte Namen binden?
Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Wenn man `background_images` meint, sollte man nicht nur `bg` schreiben. Und wieso ein `OptionMenu`-Objekt` an den Namen `lbl_bg` gebunden werden sollte, verstehe ich gar nicht. Wofür ist denn `lbl` hier die Abkürzung?
Wie Du selbst bemerkt hast, sind `PhotoImage`-Objekte keine sinnvollen Werte für ein `OptionMenu`. Da bräuchte man zwei Datenstrukturen. Einmal die Texte die angezeigt werden sollen, und dann beispielsweise ein Wörterbuch das die Texte auf die passenden `PhotoImage`-Objekte abbildet.
Warum ist beim `OptionMenu` ein getrennter `config()`-Aufruf? Das kann man beim erstellen des Objekts doch bereits alles angeben.
`btt_bg` im Hauptprogramm und `lbl_bg` in der `background()`-Funktion sind unsinnig, weil da der Wert `None` dran gebunden wird. Das ist der Rückgabewert von der `pack()`-Methode.
Das vorgehen jedes mal ein neues `Label` zu erstellen ist falsch. Man erstellt das `Label` einmal und ändert dort dann einfach das Bild, das in dem Label angezeigt wird.
Funktions- und Methodennamen werden üblicherweise nach der Tätigkeit benannt, die sie durchführen, damit der Leser weiss was dort gemacht wird, und um sie von eher passiven Werten unterscheiden zu können. `background` wäre ein guter Name für einen Wert der einen Hintergrund repräsentiert, aber nicht für eine Funktion, die einen Hintergrund setzt oder aktualisiert.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
from functools import partial
from pathlib import Path
IMAGE_DIRECTORY_PATH = Path("brackets")
def update_background(text_to_image, label, text_var):
label["image"] = text_to_image[text_var.get()]
def main():
root = tk.Tk()
root.title("1 WLT - Paring")
root.iconbitmap("wesnoth_editor-icon.ico")
root.configure(bg="#272a33")
root.geometry("1400x700")
root.resizable(False, False)
game_mode_var = tk.StringVar()
game_mode_texts = [
# 8 Players
"2x4 DE Top4",
"Swiss Top4",
"bo3 Top4",
# 4 Players
"4 DE",
"bo3 Top2",
"RR 3 cases",
]
game_mode_text_to_image = {
game_mode_text: tk.PhotoImage(
file=IMAGE_DIRECTORY_PATH / f"{game_mode_text}.png"
)
for game_mode_text in game_mode_texts
}
background_label = tk.Label(root)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
tk.OptionMenu(
root,
game_mode_var,
*game_mode_texts,
bg="RED",
activebackground="RED",
fg="BLUE",
activeforeground="BLUE",
font=("Arial", 12),
width=10,
).place(x=10, y=50)
tk.Button(
root,
text="Gamemode",
command=partial(
update_background,
game_mode_text_to_image,
background_label,
game_mode_var,
),
).pack()
root.mainloop()
if __name__ == "__main__":
main()