Mailing List Archive

Tkinter List of Canvases
Hello,

I have a list of canvas of images. I would like to display all the images. But it displays the last image. Here is my code.

from tkinter import *
from PIL import Image, ImageTk

root = Tk()

canvas_width = 265
canvas_height = 130
canvases = []

r, c = 0, 0

for tile in tiles:
img = tile.image
photo = ImageTk.PhotoImage(image=img)
can = Canvas(root, width=canvas_width, height=canvas_height)
can.create_image(0, 0, image=photo, anchor=NW)
canvases.append(can)
can.grid(row=r, column=c)

c += 1
if c % 5 == 0:
r += 1
c = 0


root.mainloop()

Please help.
Thanks.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter List of Canvases [ In reply to ]
On 2020-11-10 10:01, ChalaoAdda wrote:
> Hello,
>
> I have a list of canvas of images. I would like to display all the images. But it displays the last image. Here is my code.
>
> from tkinter import *
> from PIL import Image, ImageTk
>
> root = Tk()
>
> canvas_width = 265
> canvas_height = 130
> canvases = []
>
> r, c = 0, 0
>
> for tile in tiles:
> img = tile.image
> photo = ImageTk.PhotoImage(image=img)
> can = Canvas(root, width=canvas_width, height=canvas_height)
> can.create_image(0, 0, image=photo, anchor=NW)
> canvases.append(can)
> can.grid(row=r, column=c)
>
> c += 1
> if c % 5 == 0:
> r += 1
> c = 0
>
>
> root.mainloop()
>
You need to keep a reference to the images. In your code, 'photo' still
refers to the last photoimage, so that's why it's displayed; there are
no references to the others, so they're garbage-collected. (You probably
expected that 'create_image' would keep a reference to the image, but it
doesn't. tkinter has its idiosyncrasies!)

Try adding a list for the photoimages:

...
photos = []

for tile in tiles:
img = tile.image
photo = ImageTk.PhotoImage(image=img)
photos.append(photo)
can = Canvas(root, width=canvas_width, height=canvas_height)
...
--
https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter List of Canvases [ In reply to ]
On Tue, 10 Nov 2020 17:21:04 +0000, MRAB wrote:

> On 2020-11-10 10:01, ChalaoAdda wrote:
>> Hello,
>>
>> I have a list of canvas of images. I would like to display all the
>> images. But it displays the last image. Here is my code.
>>
>> from tkinter import *
>> from PIL import Image, ImageTk
>>
>> root = Tk()
>>
>> canvas_width = 265 canvas_height = 130 canvases = []
>>
>> r, c = 0, 0
>>
>> for tile in tiles:
>> img = tile.image photo = ImageTk.PhotoImage(image=img)
>> can = Canvas(root, width=canvas_width, height=canvas_height)
>> can.create_image(0, 0, image=photo, anchor=NW)
>> canvases.append(can)
>> can.grid(row=r, column=c)
>>
>> c += 1
>> if c % 5 == 0:
>> r += 1 c = 0
>>
>>
>> root.mainloop()
>>
> You need to keep a reference to the images. In your code, 'photo' still
> refers to the last photoimage, so that's why it's displayed; there are
> no references to the others, so they're garbage-collected. (You probably
> expected that 'create_image' would keep a reference to the image, but it
> doesn't. tkinter has its idiosyncrasies!)
>
> Try adding a list for the photoimages:
>
> ...
> photos = []
>
> for tile in tiles:
> img = tile.image photo = ImageTk.PhotoImage(image=img)
> photos.append(photo)
> can = Canvas(root, width=canvas_width, height=canvas_height)
> ...

Thanks a lot.

--
https://mail.python.org/mailman/listinfo/python-list