Seite 1 von 1

Problem bei Buttons mit Bildern

Verfasst: Sonntag 12. September 2010, 17:59
von BluePhoenix
Hallo,
ich habe ein kleines aber feines Problem. Ich wollte einem Button ein Bild zuweisen und habe dazu zum Testen folgenden Code benutzt:

Code: Alles auswählen

import Tkinter as tk

hf=tk.Tk()
mf=tk.Frame(hf)
photo=tk.PhotoImage(file="E:\\MyProggs\\ContactList\\ctl\\Images\\Add_Entry.gif")
b=tk.Button(mf, bg="black", foreground="blue", activeforeground="yellow", activebackground="black", font="Verdana")
b.config(image=photo)
b.pack()

mf.pack()
hf.mainloop()
Hat soweit super funktioniert, aber wenn ich diesen Code in das eigentliche Programm einbinde, erscheint auf dem Button kein Bild sondern nichts. Außerdem ist der Knopf dann nicht mehr anklickbar, aber es wird keine Fehlermeldung ausgegeben.

Auszug aus dem Hauptprogramm:

Code: Alles auswählen

def dButton(mf, text='', x=0, y=0, w=100, h=20, fg=standardbuttonfg, bg=standardbuttonbg, afg=standardbuttonafg, abg='', command='', font='Arial %s' %(standardschriftgroesse), width=-1, border=1, anchor='center', focus=0, indicatoron=0, selectcolor=standardbuttonafg, image=""):
    if width!=-1:
        w=width
    if abg=='':
        abg=bg

    b=tk.Button(mf, text=text, bg=bg, foreground=fg, activeforeground=afg, activebackground=abg, font=font, command=command)
    b.place(x=x, y=y, width=w, height=h)
    if image != "":
        photo=tk.PhotoImage("Image\\"+image)
        b.config(image=photo)
    if focus==1:
        b.focus_set()
        
    return b
(Anmerkung: mf ist die tk.Frame-Instanz)
Und der entsprechende Aufruf:

Code: Alles auswählen

dButton(mf, image="Add_Entry.gif", w=300, h=40, x=0, y=0, command=lambda: Add(mf))
    

Jetzt die Frage: Was ist falsch?

Liebe Grüße,
ein verwirrter Python-Nutzer

Re: Problem bei Buttons mit Bildern

Verfasst: Sonntag 12. September 2010, 18:11
von BlackJack
@BluePhoenix: Du musst auf der Python-Seite eine Referenz auf das Bildobjekt behalten. Wenn Python darauf keine Referenz mehr hat und das Objekt im Speicher freigibt, ist das auch von Tk nicht mehr verwendbar.

Von `place()` sollte man übrigens die Finger lassen. Das ist nur in sehr wenigen Ausnahmefällen die richtige Vorgehensweise.

Re: Problem bei Buttons mit Bildern

Verfasst: Sonntag 12. September 2010, 23:32
von BluePhoenix
BlackJack hat geschrieben:@BluePhoenix: Du musst auf der Python-Seite eine Referenz auf das Bildobjekt behalten. Wenn Python darauf keine Referenz mehr hat und das Objekt im Speicher freigibt, ist das auch von Tk nicht mehr verwendbar.
Und wie macht man das?

Re: Problem bei Buttons mit Bildern

Verfasst: Montag 13. September 2010, 03:04
von BlackJack
@BluePhoenix: Mit so einer Funktion? Gute Frage. Man könnte das `PhotoImage`-Exemplar an das `Button`-Exemplar binden und dokumentieren, dass der Aufrufer entweder dafür sorgen muss, dass eine Referenz auf den `Button` weiterhin besteht, oder dass er zumindest das `PhotoImage`-Attribut am Leben erhalten muss.

Re: Problem bei Buttons mit Bildern

Verfasst: Montag 13. September 2010, 11:31
von kaytec
Hallo BluePhoenix,

Du musst aus Deinen Bildern schon innerhalb des "mainloops" ein "TkImage" erzeugen. Alle Deine später verwendeten Bilder müssen auch "TkImages" sein. Erstelle eine list oder dict und werfe dort Deine Bilder als "TkImage" rein. Falls Du die Bilder in einer "Extraklasse" erzeugst, müssen sie auch dort als "TkImage" generiert werden. Das ist meine Erfahrung mit Bildern und Tkinter, evt. geht es auch anders, doch ich habe es nur so zum Laufen gebracht.

Gruß Frank

Re: Problem bei Buttons mit Bildern

Verfasst: Montag 13. September 2010, 15:44
von BluePhoenix
Hallo Kaytec,
es hat zwar ein bischen gedauert, aber letzten Endes habe ich das Problem so wie du es beschrieben hast gelöst bekommen.
Vielen Dank für die schnelle Hilfe euch beiden.

Liebe Grüße,
BluePhoenix

Re: Problem bei Buttons mit Bildern

Verfasst: Montag 13. September 2010, 20:50
von kaytec
Hallo BluePhoenix,

BlackJack hat immer recht, doch er kann es nicht immer "lowlevel" erklären - oder er will es nicht ! :D

Gruß Frank