0

Code:

import tkinter, os
from PIL import ImageTk, Image

def sortFileImages(files):
    black = [i for i in files if 'black' in i]
    white = [i for i in files if 'white' in i]
    pawns = [[i]*7 for i in files if 'pawn' in i]
    return black + pawns[0] + [' ']*32 + pawns[1] + white

files = sortFileImages(files=os.listdir("web/images/"))
root = tkinter.Tk()

index = 0
for r in range(8):
    for c in range(8):
        if files[index] != ' ':
            img = ImageTk.PhotoImage(Image.open('web/images/{}'.format(files[index])).resize((64,64)))
        else:
            img = ImageTk.PhotoImage(Image.new('RGB', (64,64)))
        label = tkinter.Label(root, image=img, borderwidth=8)

        # Color the grid squares
        if (r%2 == 0 and c%2 == 0) or (r%2 == 1 and c%2 == 1):
            label.configure(background='grey')
        else:
            label.configure(background='white')
        
        label.grid(row=r,column=c)
        index += 1

root.mainloop()

Variable Value:

files

['black-bishop.png', 'black-bishop2.png', 'black-king.png', 'black-knight.png', 'black-knight2.png', 'black-pawn.png', 'black-queen.png', 'black-rook.png', 'black-rook2.png', 'black-pawn.png', 'black-pawn.png', 'black-pawn.png', 'black-pawn.png', 'black-pawn.png', 'black-pawn.png', 'black-pawn.png', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'white-pawn.png', 'white-pawn.png', 'white-pawn.png', 'white-pawn.png', 'white-pawn.png', 'white-pawn.png', 'white-pawn.png', 'white-bishop.png', 'white-bishop2.png', 'white-king.png', 'white-knight.png', 'white-knight2.png', 'white-pawn.png', 'white-queen.png', 'white-rook.png', 'white-rook2.png']

I know this isn't the proper order but I just want to get it displayed on the board right now.

Output:

Chess board output I am getting

Question:

I was expecting to get pieces on each square of the the top 2 and bottom 2 rows.

  1. Why is that not the case?
  2. Also why is the rook surrounded by a black box? My image does not have that box.

Edit:

Using @Boendal answer, I get the following:

new board with a few missing pieces

Why do some squares have the black square in the center (especially where the pieces are)?

Edit #2:

Dark squares were due to images not being transparent.

Fixed by converting them to transparent using the information found here

Community
  • 1
  • 1
lbragile
  • 7,549
  • 3
  • 27
  • 64
  • If someone can let me know how to include the png files that I used (pieces) in the question above, that would be great! – lbragile Dec 14 '19 at 03:12
  • 1
    there isn't a way through the SO question interface that I can think of... – Legorooj Dec 14 '19 at 03:13
  • @Legorooj ok that's what I thought as I couldn't find it. In any case, the images are just chess pieces but any image would be fine as long as I can get it to display on each square of the 4 rows I mentioned. – lbragile Dec 14 '19 at 03:17
  • 1
    Alright we'll have a look at your code. It's likely that we won't even need then - a second/umpteenth pair of eyes will spot what you don't error-wise. – Legorooj Dec 14 '19 at 03:19
  • 2
    Duplicate of *every question about disappearing Tkinter images* on this site: you aren't saving a reference to your images (other than the most recent one), so they get garbage-collected. – jasonharper Dec 14 '19 at 03:32
  • 1
    as @jasonharper said you have to keep all `img` (ie. on list or assing to `label.img` like in answer) to keep `PhotoImage` in memory. If you assign new `PhotoImage` to `img` then it removes previous image from memory and you can't see it. It is a bug in [PhotoImage](http://effbot.org/tkinterbook/photoimage.htm) – furas Dec 14 '19 at 03:42
  • @jasonharper Can you link to one, so that we may flag it as a duplicate? – AMC Dec 14 '19 at 06:38
  • @AlexanderCécile Sure that thing with the reference is already asked, but the problem with the black square/transparent is something else so I don't think you can say that it is a duplicate. – Boendal Dec 14 '19 at 11:59

1 Answers1

1

what you are missing is to keep a reference of your image.

label = tkinter.Label(root, image=img, borderwidth=8)
label.image=img

Should solve the problem. Also you can replace your if

if (r%2 == 0 and c%2 == 0) or (r%2 == 1 and c%2 == 1):

with

if r%2 == c%2:

Reference: http://effbot.org/tkinterbook/photoimage.htm

@Edit about the black background:

If I use your code I got the whole board with black squares but I don't have the images. If I use the following code (for me it will always go into the else part):

if files[index] != ' ':
    img = ImageTk.PhotoImage(Image.open('web/images/{}'.format(files[index])).resize((64,64)))
    label = tkinter.Label(root, image=img, borderwidth=8)
    label.image = img
else: # Always jump into else because my files is filled with ' '
    label = tkinter.Label(root, image='web/images/{}'.format("blank.png"), borderwidth=8)

With this I fill the empty fields with an image that is fully transparent with 64x64. It works fine for me and no weird size and no black squares

You need an image with full transparency 64x64. Create one with photoshop or gimp.

About the black squares behind the figures I think there is something wrong with the figures (black-pawn and the towers).

Boendal
  • 2,496
  • 1
  • 23
  • 36
  • Thank you, that seems to have fixed the issue of only giving 1 piece. However, I still get black squares in the center of some coordinate squares as shown in my edited post. Why is that? – lbragile Dec 14 '19 at 03:46
  • I checked it out, what you did is essentially say if there is no piece then just have nothing there, which makes the board look a bit weird. I checked the code and it does go into the `if` 16 times then `else` 32 times then `if` 16 times as expected. – lbragile Dec 14 '19 at 04:05
  • @lbragile fill with a full transparency image 64x64 – Boendal Dec 14 '19 at 04:29
  • got it to work based on your suggestions! Thank you very much. – lbragile Dec 14 '19 at 04:32