Mit PIL Bild in canvas anzeigen

Fragen zu Tkinter.
Antworten
Opa Hansi
User
Beiträge: 13
Registriert: Sonntag 12. März 2023, 10:21

Hallo,

ich möchte ein Bild in einem Canvas anzeigen. Das klappt gut. Wenn ich aber die gleichen Programzeilen über eine Funktion aufrufe, wird das Bild nicht angezeigt. Wenn aber ein Programmfehler (hier x=y) auftritt, wird das Bild angezeigt.
canvas.create_text oder canvas.create_line funktionieren einwandfrei.

Code: Alles auswählen

# Import the required Libraries
from tkinter import *
from PIL import Image, ImageTk

def formanz(canvas, nkorr):
    img=Image.open("bild.jpg")
    img=img.resize((100,180), Image.LANCZOS)
    img=ImageTk.PhotoImage(img)
    canvas.create_image(50+nkorr, 50, anchor="nw", image=img)
    canvas.create_text(5+nkorr,15, text="Text",anchor="w",fill="blue")
    #x=y

# Create an instance of tkinter frame
root = Tk()

# Set the geometry of tkinter frame
root.title("Formulargenerator")
root.geometry("704x400+20-20")
fr=Frame(root)
fr.place(x =1, y =1, width=700, height=390)


# Create a canvas widget
canvas= Canvas(fr, width=700, height=390,bg="beige")
canvas.place(x =2, y =30)

# Load an image
img=Image.open("bild.jpg")
img=img.resize((100,180), Image.LANCZOS)
img=ImageTk.PhotoImage(img)

# Add image to the Canvas Items
canvas.create_image(50, 50, anchor="nw", image=img)

canvas.create_text(5,15, text="Text",anchor="w",fill="blue")

formanz(canvas,300)

root.mainloop()
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist ein Klassiker. Das Bild wird vom Python garbage collector abgeräumt. Und dann war es das. Um das zum funktionieren zu bringen, musst du das Bild am Leben erhalten. Da man üblicherweise mit Objekten in der GUI-Programmierung arbeitet, bietet sich dafür ein self-Attribut an.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

*-Importe benutzt man nicht und auch keine Variablennamen mit kryptischen Abkürzungen. place benutzt man nicht und auch keine fixen Fenstergrößen.
Was soll ein ›nkorr‹ sein? oder eine ›formanz‹?
Statt Strings benutzt man die Tk-Konstanten für Positionsangaben.

Das Problem ist, dass Bilder nur solange dargestellt werden, so lange es noch eine Referenz auf das Image-Objekt gibt. Diese Referenz mußt Du selbst verwalten.

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk

def display_image(canvas, x_shift):
    img = Image.open("bild.jpg")
    img = img.resize((100,180), Image.LANCZOS)
    img = ImageTk.PhotoImage(img)
    canvas.create_image(50 + x_shift, 50, anchor=tk.NW, image=img)
    canvas.create_text(5 + x_shift, 15, text="Text", anchor=tk.W, fill="blue")
    return img

def main():
    root = tk.Tk()
    root.title("Formulargenerator")
    frame = tk.Frame(root)
    frame.pack()

    # Create a canvas widget
    canvas = tk.Canvas(framee, width=700, height=390, bg="beige")
    canvas.pack()

    # Load an image
    img = Image.open("bild.jpg")
    img = img.resize((100,180), Image.LANCZOS)
    img = ImageTk.PhotoImage(img)

    # Add image to the Canvas Items
    canvas.create_image(50, 50, anchor=tk.NW, image=img)
    canvas.create_text(5, 15, text="Text", anchor=tk.W, fill="blue")
    images = []
    images.append(display_image(canvas, 300))
    root.mainloop()

if __name__ == "__main__":
    main()
Opa Hansi
User
Beiträge: 13
Registriert: Sonntag 12. März 2023, 10:21

Danke,
das funktioniert gut. Jetzt muss ich es noch begreifen und in mein Programm einbauen!
Antworten