sjn
sjn

Reputation: 45

How to fix Tkinter canvas overlapping image?

Hey guys i have a simple Chessboard made in python with Tkinter, i am trying to add images of pieces to the board at a specific row and column but the canvas keeps overlapping the image. Please help!

Here is my board code:

    class GameBoard(tk.Frame):

    def __init__(self, parent, rows=8, columns=8, size=75, color1="white", 
    color2="lightgrey"):
    '''size is in pixels'''

        self.rows = rows
        self.columns = columns
        self.size = size
        self.color1 = color1
        self.color2 = color2
        self.pieces = {}

        canvas_width = columns * size
        canvas_height = rows * size

        tk.Frame.__init__(self, parent)
        self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,
                            width=canvas_width, height=canvas_height, background="white")
         self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2)

And here is my image placing code, i have put the image placement at 600 by 600 just for testing purposes.

 self.canvas.WhiteKnight = tk.PhotoImage(file = 'E:\\Final Project + 
       Report\\Pieces\\WhiteKnight.png')
 self.canvas.create_image(600,600, image = self.canvas.WhiteKnight, anchor = 'c')

Here you can see the image showing but being overlapped

Any help would be much appreciated!

Upvotes: 0

Views: 1945

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385890

Like with most graphics tools, items placed on a canvas have a z-index (or in tkinter parlance, a stacking order). By default, items are "stacked" in the order that they are created.

It appears that you are creating the images first, and the board last. A simple solution is to reverse the order and create the board first.

If that is impractical, you can use the lift method of the canvas to lift one or more pieces above others.

For example:

item_id = self.canvas.create_image(...)

<other canvas objects created here>

self.canvas.lift(item_id)

If you provide a tag for the items (such as "piece"), you can lift all pieces above everything else with that tag.

Here's a complete example, using text instead of images to keep the example simple. Run the program, then click the "lift" button to see the images appear in the middle of the board.

import tkinter as tk

image_data = '''
    R0lGODlhEAAQAOYAAElJSU5OTlFRUVJSUlNTU1hYWFtbW2FhYWJiYmRkZGtra21t
    bW5ubm9vb3FxcXl5eYCAgIGBgYKCgoODg4WFhYeHh4mJiYyMjI+Pj5ycnJ6enqCg
    oKGhoaOjo6Wlpaampqenp6ioqKqqqqurq6ysrLCwsLGxsbKysrW1tbe3t7m5ubq6
    ury8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvL
    y8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tTU1NXV1dbW1tjY2NnZ2dvb29zc3N3d3d7e
    3uLi4uTk5OXl5efn5+np6e3t7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAACH5BAkAAFIALAAAAAAQABAAAAfDgFKCgzs3NIOIiVI3Tk0k
    ioJBPjpSMktKJ1IkIIhASVFIMi5FQyUkO08piDRJQ0dIpEdCOzgPDohDPDkrGRwy
    NjEpFoI4NDBGPSwSghgzMj0XFRM0UEU5Ph6IJDQrNkoKL0xCNj0miCEyKTBCBx0Y
    Gz82PBrMMSwqCQUEgiQ1MTU3RICI4QKFCEQjPhCpsSNIjhs8arTYwQARiyUfJlCg
    IWMBgw9CIAxA1CCBlAmFEEgpEAAAJCkRWpww8DJRAQEjEwUCADs=
'''

def do_lift():
    canvas.lift("piece")

root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400)
button = tk.Button(root, text="Lift", command=do_lift)
button.pack(side="top")
canvas.pack(side="top", fill="both", expand=True)

# create items before the board
image = tk.PhotoImage(data=image_data)

canvas.create_image(130, 130, image=image, anchor="center", tags=(("piece",)))
canvas.create_image(150, 150, image=image, anchor="center", tags=(("piece",)))
canvas.create_image(170, 170, image=image, anchor="center", tags=(("piece",)))
canvas.create_image(170, 130, image=image, anchor="center", tags=(("piece",)))
canvas.create_image(130, 170, image=image, anchor="center", tags=(("piece",)))

# create the board
color = "black"
for x in range(0, 300, 20):
    for y in range(0, 300, 20):
        canvas.create_rectangle(x,y,x+20, y+20, fill=color)
        color = "bisque" if color == "black" else "black"

root.mainloop()

Upvotes: 1

Related Questions