Fotos und Dropdown-Menüs in einer Reihe anordnen

Fragen zu Tkinter.
Antworten
Tommilein
User
Beiträge: 10
Registriert: Mittwoch 16. September 2020, 03:56

Hallo,
ich brauche mal wieder eure Hilfe...
Also: Mein Begehr ist, in einer Zeile meines Tk-Fensters drei Paare bestehend aus jeweils einem Bild und einem zugehörigen Dropdown-Menü zu erstellen. Dazu habe ich eine Liste mit drei Bildern sowie eine for-Schleife gebaut, wobei in jedem Schleifendurchgang ein Canvas samt Bild sowie ein Dropdown-Menü erstellt werden soll. Starte ich das Programm, klappt's mit den drei Canvas und den drei Menüs prima. Probleme machen die Bilder: Es wird lediglich das dritte Foto geliefert, die Fotos der Schleifendurchgänge 1 und 2 tauchen nicht auf.
Kann mich jemand erhellen?
Wie immer vielen herzlichen Dank im Voraus,
Tommilein

Code: Alles auswählen

import tkinter as tk

fenster = tk.Tk()
fenster.geometry('550x150')


def EK_paar():
    pass

OptionList = [
"Paar","Chi",
"Pong/verdeckt","Pong/offen",
"Kang/verdeckt", "Kang/offen"
] 

bilderListeKreise = ["Kreis_1.gif", "Kreis_2.gif", "Kreis_3.gif"]
bildVar_K1 = tk.StringVar()
bildVar_K2 = tk.StringVar()
bildVar_K3 = tk.StringVar()
bildVarListe = [bildVar_K1, bildVar_K2, bildVar_K3]

for i in range(len(bilderListeKreise)):
    leinwand = tk.Canvas(fenster, width = 32, height = 46, bg='white')
    leinwand.grid(row = 1, rowspan = 1, padx = 1, column = i, sticky = 'w')
    bild = tk.PhotoImage(file = bilderListeKreise[i])
    leinwand.create_image(0,0, anchor='nw', image = bild)

    bildOptMenu = tk.OptionMenu(fenster, bildVarListe[i], *OptionList)
    bildOptMenu.config(width = 10, font = ('Times', 8, 'italic'))
    bildOptMenu.grid(row = 1, padx = 40, column = i, sticky = 'w')

fenster.mainloop()
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo Tommilein ,
gib deinen Bilder Namen.

Code: Alles auswählen

import tkinter as tk
fenster = tk.Tk()
fenster.geometry('550x150')

def EK_paar():
    pass

OptionList = [
"Paar","Chi",
"Pong/verdeckt","Pong/offen",
"Kang/verdeckt", "Kang/offen"
]

leinwaende = {"leinwand_links":tk.Canvas(fenster),
              "leinwand_mitte":tk.Canvas(fenster),
              "leinwand_rechts":tk.Canvas(fenster)}

bilder = {"bild_0":"pinguin.pgm", "bild_1":"Tux.pgm",
          "bild_2":"Test_schuetz.pgm"}

bildVar_K1 = tk.StringVar()
bildVar_K2 = tk.StringVar()
bildVar_K3 = tk.StringVar()

bildVarListe = [bildVar_K1, bildVar_K2, bildVar_K3]

for i, (leinwand, tk_item) in enumerate(leinwaende.items()):    
    
    bilder["bild_{}".format(i)] = tk.PhotoImage(file =
                                                bilder["bild_{}".format(i)])
   
    
    leinwaende[leinwand].grid(row = 1, rowspan = 1, padx = 1,
                                   column = i, sticky = 'w')   

    leinwaende[leinwand].create_image(0,0, anchor='nw',
                                      image=bilder["bild_{}".format(i)])    

    bildOptMenu = tk.OptionMenu(fenster, bildVarListe[i], *OptionList)
    bildOptMenu.config(width = 10, font = ('Times', 8, 'italic'))
    bildOptMenu.grid(row = 1, padx = 40, column = i, sticky = 'w')

fenster.mainloop()
Gruss Peter
Sirius3
User
Beiträge: 18289
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tommilein: das Problem ist, dass Du Dir immer die Instanz des PhotoImage merken mußt, weil sonst das Bild wieder aus dem Speicher geräumt wird.

Variablen schreibt man generell komplett klein, Wenn man anfängt Variablennamen durchzunummerieren, dann will man eigentlich eine passende Datenstruktur benutzen, was Du ja auch meist tust. Datentypen haben aber in Variablennamen nichts verloren.
Über einen Index iteriert man nicht, sondern benutzt enumerate, wenn man zusätzlich einen Index braucht.
Warum benutzt Du ein Canvas, und nicht einfach ein Label?

Code: Alles auswählen

import tkinter as tk

KREIS_BILDER = ["Kreis_1.gif", "Kreis_2.gif", "Kreis_3.gif"]
OPTIONS = [
    "Paar","Chi",
    "Pong/verdeckt", "Pong/offen",
    "Kang/verdeckt", "Kang/offen",
]

fenster = tk.Tk()
option_variables = []
for column_index, bild in enumerate(KREIS_BILDER):
    option_variable = tk.StringVar()
    option_variable.image = tk.PhotoImage(file=bild)
    option_variables.append(option_variable)
    
    tk.Label(fenster, image=option_variable.image).grid(row=1, column=column_index)
    option = tk.OptionMenu(fenster, option_variable, *OPTIONS)
    option.config(width=10, font=('Times', 8, 'italic'))
    option.grid(row=1, column=column_index)

fenster.mainloop()
Tommilein
User
Beiträge: 10
Registriert: Mittwoch 16. September 2020, 03:56

Hallo Peter, hallo Sirius3,

vielen herzlichen Dank für die Infos und die Hilfe, muss ich alles gleich mal ausprobieren.
Tommilein
Antworten