Bild wird nicht angezeigt, falls aus Funktion aufgerufen

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
Plauzi94
User
Beiträge: 4
Registriert: Donnerstag 8. September 2022, 10:21

Hallo zusammen,

ich bin gerade völlig am verzweifeln, da ich das Problem nicht wirklcih nachvollziehen kann. Ich habe folgenden Code:

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk
import requests
import io

def open_image():
    headers = {
        "Authorization": "&&&&&&&&",
        
    }
    url = "&&&&&&&&&&&"

    response = requests.get(url, headers=headers, verify=False)
    jpeg_data = response.content

    jpeg_image = Image.open(io.BytesIO(jpeg_data))
    tk_image = ImageTk.PhotoImage(jpeg_image)

    new_window = tk.Toplevel()
    new_window.title("Bildvorschau")

    label = tk.Label(new_window, image=tk_image)
    label.pack()


root = tk.Tk()
root.title("Hauptfenster")

button = tk.Button(root, text="Bild anzeigen", command=open_image)
button.pack()

root.mainloop()
Header und URL habe ich jetzt mal unkenntlich gemacht, daran liegt es aber auch nicht. Das Problem ist folgendes: Im Neuen Fenster wird kein Bild angezeigt. Wenn ich dem Label einen Text, statt einem Image übergebe, wird dieser angezeigt. Jetzt könnte man denken, dass kein JPEG vom Server kommt. Es wird aber eines übergeben. Der Code funktioniert wie er soll, sobald ich alles aus der Funktion open_image () herausziehe. Wie kann das sein? Der Zugriff auf root ist in der Methode gegeben, sonst würde er mir ja auch kein Text-Label anzeigen. Am Bild selbst kann es auch nicht liegen, weil es ja ohne die Funktion funktioniert. Ich bin wirklich absolut ratlos. Hätte jemand eine Idee was die Ursache sein könnte? Vielen Dank im voraus :)
Sirius3
User
Beiträge: 17768
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist das übliche Problem, dass ein Bild nur so lange angezeigt werden kann, solange es eine Referenz auf die Bilddaten gibt. ›tk_image‹ existiert aber nach Ende der Funktion nicht mehr.
Plauzi94
User
Beiträge: 4
Registriert: Donnerstag 8. September 2022, 10:21

Das wusste ich tatsächlich nicht. Wie kann ich das Problem denn dann beheben?
Benutzeravatar
__blackjack__
User
Beiträge: 13143
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Plauzi94: Man muss halt eine Referenz auf das Bild behalten, in dem man es beispielsweise als Attribut an ein Objekt bindet das bestehen bleibt. Also hier beispielsweise das `Toplevel`- oder das `Label`-Objekt.

Hier mal an das `Toplevel`, weil man das sowieso an einen Namen binden muss wegen dem `title()`-Aufruf (ungetestet):

Code: Alles auswählen

import io
import tkinter as tk

import requests
from PIL import Image, ImageTk


def open_image():
    response = requests.get(
        "&&&&&&&&&&&",
        headers={"Authorization": "&&&&&&&&"},
        verify=False,
        timeout=None,
    )
    response.raise_for_status()
    image = ImageTk.PhotoImage(Image.open(io.BytesIO(response.content)))
    window = tk.Toplevel()
    window.title("Bildvorschau")
    window._image = image
    tk.Label(window, image=image).pack()


def main():
    root = tk.Tk()
    root.title("Hauptfenster")
    tk.Button(root, text="Bild anzeigen", command=open_image).pack()
    root.mainloop()


if __name__ == "__main__":
    main()
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Antworten