Dawid
Dawid

Reputation: 35

Positioning labels within tkinter canvas

I am making a board game with Tkinter. The board is a single picture. I don't know how to position the pawns on that picture.

I tried putting the board and the pawns on the same canvas. It worked with a single pawn, but with multiple pawns it got messy. Pawns are represented by squares with matching color (i.e. blue).

def create_grid(self):
    self.grid_frame = Canvas(window)
    self.green_frame = Canvas(window)
    self.blue_frame = Canvas(window)
    self.grid_frame.grid(row=1, column=0)
    self.green_frame.grid(row=1, column=0)
    self.blue_frame.grid(row=1, column=0)
    self.grid_picture = PhotoImage(file="grid.PNG")
    self.grid_label = Label(self.grid_frame, image=self.grid_picture)
    self.grid_label.grid(row=0, column=0, columnspan=100, rowspan=10)
    self.green_picture = PhotoImage(file="green.png")
    self.green_symbol = Label(self.green_frame, image=self.green_picture)
    self.green_symbol.grid(row=9, column=2, columnspan=100, rowspan=10)
    self.blue_picture = PhotoImage(file="blue.png")
    self.blue_symbol = Label(self.blue_frame, image=self.blue_picture)
    self.blue_symbol.grid(row=9, column=7, columnspan=100, rowspan=10)

After using the function above, both pawns that I tried to put on the board land in the middle. Yet I need to divide the canvas and place the label precisely where I want.

Here's the picture of the result I get:

enter image description here

Upvotes: 0

Views: 1643

Answers (1)

Aivaras Kazakevičius
Aivaras Kazakevičius

Reputation: 439

If your implementation does not require creating Labels, I would suggest drawing and removing canvas objects. Canvas class has simple methods like create_text() or create_image() for you to use. Here is an example of such implementation (I have used text, but you can easily change that into images by using the above mentioned method my_canvas.create_image()):

import tkinter as tk

# PARAMETERS

SIZE = 800
SQUARES = 10


def draw_board():
    i = 0
    while i < SIZE:
        canvas.create_line(0, i, SIZE, i)
        canvas.create_line(i, 0, i, SIZE)
        i += SIZE / SQUARES


def place_pawn(x, y, color):
    pos = [(x-0.5)*SIZE/SQUARES, (y-0.5)*SIZE/SQUARES]
    pawn_colors = {'blue': '#104E8B', 'green': '#008B45'}
    canvas.create_text(pos, text='P', font=('Times', 30), fill=pawn_colors[color])


root = tk.Tk()
root.minsize(SIZE, SIZE)
canvas = tk.Canvas(root, width=SIZE, height=SIZE)
canvas.pack()
draw_board()
place_pawn(2, 3, 'blue')
place_pawn(8, 6, 'blue')
place_pawn(1, 1, 'blue')
place_pawn(9, 9, 'green')
place_pawn(9, 1, 'green')

root.mainloop()

As of your implementation, you should check out how the grid manager works. I have tested it out and the code does exactly what you asked it to do. Specifying row=9 and column=5 for example won't place the Label at 9-th row and 5-th column if there are no other smaller columns and rows. Anyway, in your code you create two canvas objects for different color pawns. Then you put all canvas objects in the same cell of the grid. This creates one big canvas with the board picture and two small sized canvas objects at the center. When you put a pawn inside, canvas objects just expand to the size of pawn image and stay at the center.

Upvotes: 1

Related Questions