[Tkinter] making a list of labels callable - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: [Tkinter] making a list of labels callable (/thread-37916.html) |
making a list of labels callable - laur3333 - Aug-08-2022 Hi, I'm trying to define 5 labels as a list of labels. The reason I want to do this is that later I can iterate through the labels with a for loop in order to make updates. This is the code that works: from tkinter import * from PIL import Image, ImageTk root = Tk() root.title('some text') root.geometry('1200x800') root.configure(background='green') def resize_cards(card): our_card_img = Image.open(card) # open the image our_card_resized_image = our_card_img.resize((150, 218)) # resize the image global our_card_image our_card_image = ImageTk.PhotoImage(our_card_resized_image) # output the card return our_card_image # return the card backImage = resize_cards(f'images/pokerCards/backOfCard/back1.png') cardLabel1 = Label(root, image=backImage, bg='snow') cardLabel1.grid(sticky = W, row=0, column=0, pady=20, padx=20) cardLabel2 = Label(root, image=backImage, bg='snow') cardLabel2.grid(sticky = W, row=0, column=1, pady=20, padx=20) cardLabel3 = Label(root, image=backImage, bg='snow') cardLabel3.grid(sticky = W, row=0, column=2, pady=20, padx=20) cardLabel4 = Label(root, image=backImage, bg='snow') cardLabel4.grid(sticky = W, row=0, column=3, pady=20, padx=20) cardLabel5 = Label(root, image=backImage, bg='snow') cardLabel5.grid(sticky = W, row=0, column=4, pady=20, padx=20) root.mainloop()this code does not work: from tkinter import * from PIL import Image, ImageTk root = Tk() root.title('some text') root.geometry('1200x800') root.configure(background='green') global cardLabel #cardLabel = [] def resize_cards(card): our_card_img = Image.open(card) # open the image our_card_resized_image = our_card_img.resize((150, 218)) # resize the image global our_card_image our_card_image = ImageTk.PhotoImage(our_card_resized_image) # output the card return our_card_image # return the card for f in range(5): global cardLabel, backImage cardLabel = [] backImage = resize_cards(f'images/pokerCards/backOfCard/back1.png') cardLabel[f] = Label(root, image=backImage, bg='snow') cardLabel[f].grid(sticky = W, row=0, column=f, pady=20, padx=20) root.mainloop()It returns the following error: Thanks
RE: making a list of labels callable - menator01 - Aug-08-2022 Not sure why you are using globals but, give this a try. You need to append to thr cardlabel list. import tkinter as tk def card_back(number): img = tk.PhotoImage(file='some.png') img.image = img labels = [] for i in range(number): label = tk.Label(root) labels.append(label) labels[i]['image'] = img labels[i].grid(column=i, row=1, sticky='new', pady=20, padx=20) root = tk.Tk() card_back(5) root.mainloop() Another example import tkinter as tk from PIL import Image, ImageTk def card_back(number): img = Image.open('cardback.png') img_resized = img.resize((140, 200)) img = ImageTk.PhotoImage(img_resized) img.image = img labels = [] for i in range(number): label = tk.Label(root, bg='darkgreen') labels.append(label) labels[i]['image'] = img labels[i].grid(column=i, row=1, sticky='new', pady=20, padx=20) root = tk.Tk() root['bg'] = 'darkgreen' card_back(5) root.mainloop() RE: making a list of labels callable - laur3333 - Aug-08-2022 Thanks a lot. It works with append. * globals were a part of code I forgot to delete RE: making a list of labels callable - deanhystad - Aug-08-2022 You created a list with no elements. Then you tried to set the value of elements in the list. That is why you got an index error. Will the labels always display the same image, or will different labels display different images? If the later, your scheme of using the global variable backimage will not work. Each image needs a reference. If you have 5 cards with different images you cannot save them all in one variable (unless it is a list). In this example I save a reference to the image in a dictionary. I am assuming that I will have multiple card images that will be reused (card back and 52 face images). If I want to flip a card over to show the face (Ace clubs) I would set the card image to "...ace_clubs.png". import tkinter as tk from PIL import Image, ImageTk DEFAULT_IMAGE = f"images/pokerCards/backOfCard/back1.png" class MainWindow(tk.Tk): def __init__( self, num_cards, *, title="Cards!!!", card_image=DEFAULT_IMAGE, background="green", ): self.card_images = {} super().__init__() self.title(title) self.configure(background=background) self.cards = [tk.Label(self, bg="snow") for _ in range(num_cards)] for col, card in enumerate(self.cards): self.set_card_image(card, card_image) card.grid(sticky=tk.W, row=0, column=col, pady=20, padx=20) def set_card_image(self, card, image_file): if image_file in self.card_images: image = self.card_images[image] else: image = ImageTk.PhotoImage(Image.open(image_file).resize((150, 218))) self.card_images[image_file] = image card["image"] = image MainWindow(5).mainloop() RE: making a list of labels callable - laur3333 - Aug-09-2022 Yes, that's correct, I will use multiple images. Thanks a lot for the explanations and for the example. They are really useful. |