python-3.xtkinterphotoimage

Image not showing up when file updated/changed Tkinter


I have an image that I have placed, which works perfectly fine, but when I want to change it to a different image it doesn't change. The cards images have the same names as the ones in the list, i.e. 2C = 2 of Clubs.

root=Toplevel()
root.state('zoomed')
root.config(bg='#1b800b')
root.title('PokerChamp')


all_cards  = ['2C','3C','4C','5C','6C','7C','8C','9C','10C','JC','QC','KC','AC','2D','3D','4D','5D','6D','7D','8D','9D','10D','JD','QD','KD','AD','2S','3S','4S','5S','6S','7S','8S','9S','10S','JS','QS','KS','AS','2H','3H','4H','5H','6H','7H','8H','9H','10H','JH','QH','KH','AH']

play_card1 = PhotoImage(file='files/cards/red_back.png')
card6 = Label(root, image=play_card1, bd=0)
card6.place_forget()
select_cards()

def select_cards():
    card6.place(relx=0.45, rely=0.75)
    player_card1 = random.choice(all_cards)
    play_card1 = PhotoImage(file = f'files/cards/{player_card1}.png')
    root.update()

Solution

  • When you load the first image you give it the name play_card1 in the global namespace.

    The function select_cards() is a local namespace and when you assign a value to player_card1 it is a local name is not associated with the label and which will be garbage collected when the function ends.

    The usual way to do this is to assign the new image to the label and then to save a reference to the image in the label object so the reference to tha image will not be lost as the function exits. See my example (I used slightly different images than you...):

    from tkinter import *
    import random
    
    root = Toplevel()
    root.config(bg='#1b800b')
    root.title('PokerChamp')
    
    all_cards  = ['chapman','cleese','gilliam','idle','jones','palin']
    
    play_card1 = PhotoImage(file='images/beer.png')
    card6 = Label(root, image=play_card1, bd=0)
    card6.place_forget()
    
    def select_cards():
        card6.place(relx=0.5, rely=0.5, anchor='center')
        player_card1 = random.choice(all_cards)
        play_card1 = PhotoImage(file = f'images/{player_card1}.png')
        card6.config(image=play_card1)  # Assign new image to label card6
        card6.image = play_card1        # Keep a reference to image
        root.update()
    
    select_cards()
    

    Also I would advise against using the name root for a Toplevel() window as root is usually used for the root window.