Search code examples
pythontkinterpython-3.7chesspython-chess

Tkinter button not displaying image despite existing reference


In a GUI based chess game that I have created using tkinter in Python I'm using images to display the chess piece on the grid button. The image .png files are located within a folder in the same directory as the program. When I run the code the images don't display on the button. I found this question which says that I need to retain a reference for the variable. My code retains a reference and despite that the image does not display. (Keep in mind that for now the image will only display for black pawns)

Here is the code that creates the button (Python 3.7):

class Space(tk.Button):
color = 0
inst_num = 0

def __init__(self, name, root, player=None):
    Space.inst_num += 1
    Space.color += 1
    Space.color += (1 if Space.color % 9 == 0 else 0)

    self.root = root
    self.name = name
    self.player = player

    super().__init__(self.root, image=P_ABBREVIATIONS[self.name], bg=('grey' if Space.color % 2 == 0 else 'white'),
                     fg=('black' if player == 'B' else 'grey22'), height=80, width=80, relief='flat')

And here is the code where the PhotoImage object is stored:

if __name__ == '__main__':
    master = tk.Tk()

P_ABBREVIATIONS = {'Pawn': tk.PhotoImage(r'icons\b_pawn.png').subsample(8, 8)}      # For now only Pawn TODO: add other chess peice PhotoImage objects 

if __name__ == '__main__':
    Chess = ChessBoard(master)
    master.mainloop()

For the whole code go to: https://pastebin.com/JXxBsLCz


Solution

  • The problem is that you're creating the image incorrectly. The path needs to be assigned to the file option. The first positional argument is assigned as the internal name of the image. Thus, if you omit file=, you're assigning a name but you aren't giving the image any data.

    tk.PhotoImage(file=r'icons\b_pawn.png')
                  ^^^^^