0

So I'm writing basic stuff in python with tkinter and PIL and the problem here is that when I run the program, only the last button show the image of the item I asked him to show.

So my program was expected to extract name of items from lines containing the name of a game Champion in a txt document. Each line in the document looks like "ItemName/stat1/stat2/stat3/ChampionName".

The code was then supposed to create buttons with a picture of the item on it(I made sure to name the pngs and the item name in the .txt the same and to put everything in the same folder) but in the end, only the last button had an image on it.

What I tried :

  • I tried to reduce the number of elements in the txt, it didn't work
  • I then thought that the problem was that the variable icon being updated, the image shown would disappear. So I tried to make an array but it didn't work either because what I put in isn't an int value, I know it's about the 'i' but I don't know if I can put something else appropriate.

My first attempt :

from PIL import Image, ImageTk 
import tkinter as tk

itemwindo = tk.Tk()
itemwindo.title("Items")

data = open("Ressource.txt","r")
for line in data:
    if 'Vi' in line:
        (a,b,c,d,e) = line.split("/")
        icon = ImageTk.PhotoImage(Image.open(a + '.png'))
        bt = tk.Button(itemwindo,image=icon)
        bt.pack()
itemwindo.mainloop()

And my second with arrays :

data = open("Ressource.txt","r")
imglist = arr.array('i')
for line in data:
    if 'Vi' in line:
        (a,b,c,d,e) = line.split("/")
        icon = ImageTk.PhotoImage(Image.open(a + '.png'))
        imglist.extend([icon])
        p = len(imglist)
        bt = tk.Button(itemwindo,image=imglist[p])
        bt.pack()
itemwindo.mainloop()

I would like each button to display the picture of the affiliated item on it.

Miraj50
  • 4,257
  • 1
  • 21
  • 34
Deltix
  • 35
  • 3

1 Answers1

1

In the loop that cretes the buttons you use the same name for every image. This creates a new object every iteration and the previous buttons can no longer find a reference to the previous image.

To fix this you can assign the image attribute of the button at creation and then it does no longer make any difference if you reuse the icon or bt name. Study the example below:

import tkinter as tk

itemwindo = tk.Tk()

file_list = ['beer.png', 'test.gif']
for file in file_list:
    icon = tk.PhotoImage(file=file)
    bt = tk.Button(itemwindo, image=icon)
    bt.pack()
    bt.image = icon # Save reference to icon in button

itemwindo.mainloop()
figbeam
  • 7,001
  • 2
  • 12
  • 18
  • The problem is that I want the code to be flexible in case of users adding items in the document and their icons so I can't just right down the "name.png" – Deltix Dec 26 '18 at 02:20
  • It's just an example of the mechanism of saving a ref to the image in a button attribute. You can do this with any image regardless of its name or if it's dynamically entered or not. – figbeam Dec 26 '18 at 10:45
  • Im about to ask a really basic questions sorry but : How do I add elements to file_list ? I suppose this doesn't work ? `file_list = [] file_list.extend([name])` And also I don't get how your `bt.image = icon` works Sorry for asking this much question but I really am beginning and, without knowing anybody who can help me, it really is a pain sometimes – Deltix Dec 26 '18 at 15:11
  • Here is a good basic explanation: [Python List](https://www.programiz.com/python-programming/list). – figbeam Dec 27 '18 at 16:28