Zugriff auf Image welches in anderer Klasse definiert wurde

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
ereetzer
User
Beiträge: 9
Registriert: Samstag 24. September 2022, 13:08

Hallo,

zum einen würde ich gern verstehen wie es funktioniert und zum anderen finde ich es übersichtlicher wenn ich meine ganzen Icons die ich in der Oberfläche des Programm verwende in eine extra Classe auslagern könnte.
Ausserdem, so der Gedanke könnte ich dann in allen anderen Programmteilen auf die Icons zugreifen.

Die Idee ist also eine Klasse mit den Image zu erzeugen:

Code: Alles auswählen

class Icons:
    def __init__(self):
        self.img_test = tk.PhotoImage(file="icons\\scales-16.png")
        self.img_pressure = u.s.w.
        self.img_pulse = u.s.w.
in der anderen Klasse, bei welcher ich dieses Image verwenden möchte dann dies an der entsprechende Stelle im Code:

Code: Alles auswählen

    def create_bottomframe():
        test = Icons()
        print(test)
        button_close = tk.Button(self.bottomframe, text="   schliessen", image=test.img_test, compound=tk.LEFT, command=self.schliessen)
create_bottomframe ist eine Methode welche in der __init__ aufgerufen einer anderen Klasse aufgerufen wird.

Der Code wird auch ausgeführt, allerdings hat der Button kein Bild und ist auch nicht anklickbar. Wenn die Imagezuweisung weggelassen wird, ist die Funktio ndes Buttons da, nun natürlich leider ohen das Bild.

Kann mir jemand weiterhelfen?

Viele Grüße
loph
User
Beiträge: 4
Registriert: Freitag 3. November 2023, 22:32

Ohne die Details der Implementierung zu kennen, tippe ich mal darauf auf folgendes:

Nach dem Ende der Funktion 'create_bottomframe' wird die Variable 'test' wieder freigegeben. Da die Benutzerinteraktion aller Voraussicht nach in anderen Funktionen implementiert ist, kann der Button auf das Icon() dann nicht zugreifen, da er 'test' nicht kennt.
Sirius3
User
Beiträge: 17844
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist das typische Problem, dass immer eine Referenz auf das Imageobjekt existieren muss. Hier nur etwas versteckt, weil das imageobjekt in einer Klasseninstanz steckt, die nach Ende der Funktion freigegeben wird.
ereetzer
User
Beiträge: 9
Registriert: Samstag 24. September 2022, 13:08

Ah, danke Euch beiden.

Nun habe ich also geschwind mal eine Instanz von Icons in der __init__ der aufrufenden Klasse erstellt und greife in der Funktion create_bottomframe dann darauf zu und nicht mehr in der Funktion selbst.
Das funktioniert dann auch.
Ist das so dann korrekt umgesetzt?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich finde nicht. Weil du ja ein Icons-Objekt mit *allen* Icons anlegst, aber zumindest leicht vorstellbar ist, dass man ja verschiedene GUI-Klassen hat, bei denen man Icons benutzen will. Womit man dann unnoetig viele Kopien der eigentlichen PhotoIimage-Objekte rumliegen hat.

Das hier ist einer der Grenzfaelle fuer mich, wo ich durchaus ueber eine globale Instanz mit lazy Initialisation nachdenken wuerde. Weile diese Daten ja im Grunde statischer Natur sind, und sich ueber die Lebenszeit des Programmes nicht veraendern. Gleichzeitig darft man aber AFAIK PhotoImages erst dann erzeugen, wenn tkinter schon das Tk-Objekt erzeugt hat. Darum also lazy.

Alternativ kann man natuerlich auch ein Icons-Objekt in der main zB erzeugen, und einfach immer reinreichen. Damit gibt es auch nur eine Kopie. Ist eineGeschmacksfrage, pedantische Naturen vermeiden globalen Zustand unter allen Umstaenden - ich halte das hier wie gesagt vertretbar.
Antworten