-1

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

Manusman
  • 57
  • 6
  • 1
    Please reduce this code down to a [mcve]. If the problem is with the display of the image, we only need one image and the code that displays it. _For the purpose of this question_ we don't care about Bishops, Pawns, etc. nor do we care about self.information. – Bryan Oakley Mar 25 '20 at 14:15
  • @BryanOakley Thank You for your comment I edited the code to not display unneeded information – Manusman Mar 25 '20 at 14:24
  • Yo have two `if __name__ == '__main__'` blocks. Is that intentional? Also, we can't run this code since you rely on `ChessBoard` and didn't provide a stub for that. – Bryan Oakley Mar 25 '20 at 14:28
  • @BryanOakley It is intentional since you cannot create a PhotoImage object before creating a Tk instance and in this case i wanted P_ABBREVIATIONS to exist even if the file is imported. As for ChessBoard the class is not important for the purpose of the question. – Manusman Mar 25 '20 at 14:37
  • Are you certain that you're running a version of tkinter that supports png? As an experiment, replace the png file with a gif and see if your code works. – Bryan Oakley Mar 25 '20 at 14:38
  • @BryanOakley I am certain since when i first implemented the images I made it create a new photoImage even for the same chess piece every time it entered Space.__init__. This was very inefficient and it took around 15 - 20 seconds to load the window, so instead i decided to define the objects at the beginning so the program can just use those variables without creating new ones for every piece. – Manusman Mar 25 '20 at 14:45

1 Answers1

1

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')
              ^^^^^
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685