2

I wanted to create a chess program using OOP. So I made a superclass Pieces, a subclass Bishop, and a UI class GameUI. I created a canvas in the class GameUI. I wanted, that when I instantiate an object bishop in the class GameUI, it shows an Image from a bishop, on the canvas.

The problem is, when I instantiate the Bishop, I don't see any image. So I tried to do the same with a text : instead of using the method create_image from the class Canvas, I used the method create_text, and it worked : I saw a text on the canvas. That means, the problem comes from the method create_image, and I don't understand it.

If I create an Image directly in the class GameUi, it works! but that's not what I want...

So I don't have any error message. I see the canvas (with a blue background), but no image on it.

Here's the code :

from tkinter import PhotoImage, Tk, Canvas


class Pieces:

    def __init__(self, can, color, x_position, y_position):
        self.color = color
        self.x_position = x_position
        self.y_position = y_position


class Bishop(Pieces):

    def __init__(self, can, color, x_position, y_position):

        super().__init__(can, color, x_position, y_position)

        if color == "black":
            icon_path = 'black_bishop.png'
        elif color == "white":
            icon_path = 'white_bishop.png'

        icon = PhotoImage(file=icon_path)  # doesn't see the image
        can.create_image(x, y, image=icon)


class GameUI:

    def __init__(self):

        self.windows = Tk()
        self.windows.title("My chess game")
        self.windows.geometry("1080x720")
        self.windows.minsize(300, 420)

        self.can = Canvas(self.windows, width=1000, height=600, bg='skyblue')
        
        icon = PhotoImage(file=icon_path)  # here I create the image in this class, and
        can.create_image(x, y, image=icon)  # we can see it very well

        self.bishop = Bishop(self.can, "black", 50, 50)
        self.can.pack()
        self.windows.mainloop()


app = GameUI()
Ivan Reshetnikov
  • 398
  • 2
  • 12
Sticonike
  • 47
  • 6

1 Answers1

1

To make your code work, I decided to sort of rewrite it based on this answer. It works now, but really the only thing that you needed to add was self.icon instead of icon. icon gets garbage collected since there is no further reference to it, while self.icon remains. Also, it's not entirely the same as yours was, so it probably needs a bit of rewriting too.

from tkinter import *
from random import randint

class Piece:
    def __init__(self, canvas, x1, y1):
        self.x1 = x1
        self.y1 = y1
        self.canvas = canvas

class Bishop(Piece):
    def __init__(self, canvas, x1, y1, color):
        super().__init__(canvas, x1, y1)

        if color == "black":
            icon_path = 'black_bishop.png'
        elif color == "white":
            icon_path = 'white_bishop.png'

        self.icon = PhotoImage(file=icon_path)
        self.ball = canvas.create_image(self.x1, self.y1, image=self.icon)

    def move_piece(self):
        deltax = randint(0,5)
        deltay = randint(0,5)
        self.canvas.move(self.ball, deltax, deltay)
        self.canvas.after(50, self.move_piece)

class GameUI:
    def __init__(self):
        # initialize root Window and canvas
        root = Tk()
        root.title("Chess")
        root.resizable(False,False)
        canvas = Canvas(root, width = 300, height = 300)
        canvas.pack()

        # create two ball objects and animate them
        bishop1 = Bishop(canvas, 10, 10, 'white')
        bishop2 = Bishop(canvas, 60, 60, 'black')

        bishop1.move_piece()
        bishop2.move_piece()

        root.mainloop()

app = GameUI()
cbolwerk
  • 400
  • 1
  • 8