0

I was able to recreate the issue in a much smaller, 50-line code. This is why you may see a seemingly 'useless' need for parameters and arguments.

First what the program does, is create a main window and gameboard object which is a subclass of tk.Canvas. The object then creates 8 rows and columns with alternating colors for each 120x120 square.

Then, I create the game pieces (which, will normally be done in a for loop, but this run-down example, just creates two pieces) giving them a 60x60 and a 60x120 spot respectively.

Finally I wrap it up with a simple quit button and mainloop function.


My code seems to cause a new canvas to get drawn on the GameBoard each time I try to place an image item on the board.

Now, I believe that this error stems from the GameBoard class, specifically where it calls the __init__ method from the base class.

I've tried working and reworking all different places to put each self method thinking that that might help, but to no avail.

However, if I comment out the two lines where I create the rook and pawn, then the board appears like normal. So I know that it must be caused directly by the pieces.

So, here is my attempt at a chess game. Please keep in mind it's nowhere near complete, and the code below is not an excerpt from my code, but a total recreation just to show the error.

If you see any glaring issues that have nothing to due with my actual problem, know that I'm trying my hardest to keep from repeating myself, and following the pip8 guidelines. So any input on cleanliness, or overall functionality would be greatly appreciated.


As quamrana had pointed out in the comments: The reason why I have GamePiece inherit from GameBoard, is specifically because I want to not have to worry about changing the background of the image to match the color of the space that said image is on.

import tkinter as tk
from PIL import ImageTk, Image

class GameBoard(tk.Canvas):
    def __init__(self, parent):
        self.color = ""

#where I believe my error comes from
        tk.Canvas.__init__(self, parent, height=960, width=960)
        self.grid()

#spaces created here by rows snd columns
    def create_spaces(self):
        x1, y1, x2, y2 = 0, -120, 120, 0
        for _row in range(8):
            x1, x2 = 0, 120
            y1 += 120
            y2 += 120
            self.alternate_colors()
            for _column in range(8):
                self.create_rectangle(x1, y1, x2, y2, fill=self.color)
                x1 += 120
                x2 += 120
                self.alternate_colors()

#each space created alternates between the two colors here
    def alternate_colors(self):
        if self.color == "green": self.color = "pink"
        else: self.color = "green"

class GamePiece(GameBoard):
    def __init__(self, parent, xPOS, yPOS, photo_file):
        GameBoard.__init__(self, parent)
        self.photo1 = Image.open(photo_file)
        self.photo2 = ImageTk.PhotoImage(self.photo1)
        self.create_image(xPOS, yPOS, image=self.photo2)
        self.grid()

#main window and gameboard is created here
window = tk.Tk()
gameboard = GameBoard(window)
gameboard.create_spaces()

#all pieces will eventually be created here using for loops
gamepiece1 = GamePiece(gameboard, 60, 60, "black_rook.png")
gamepiece2 = GamePiece(gameboard, 60, 120, "black_pawn.png")

#quit button and mainloop
tk.Button(window, text="Quit", command=quit, bd=5).grid(pady=40)
window.mainloop()
Maz
  • 35
  • 8
  • Why does `GamePiece` inherit from `GameBoard`? – quamrana Apr 14 '20 at 15:20
  • That's a good question. I have ```GamePiece``` inherit from ```GameBoard``` specifically because I want to not have to worry about changing the background of the image to fit whatever color space said image is on. I will update that in the actual question – Maz Apr 14 '20 at 16:13

1 Answers1

1

Inheritance means a subclass is a superclass. If your GamePiece inherits from GameBoard, then GamePiece is a GameBoard. Since GameBoard creates a canvas, so does GamePiece.

It appears you're using inheritance in an attempt to share data between objects. That is not what inheritance is for. Your GamePiece class should not be inheriting from GameBoard.

You are correctly passing in the instance of GameBoard as the first argument when creating a GamePiece, so your GamePiece should use that when drawing itself on the board. It should probably look something like this:

class GamePiece():
    def __init__(self, gameboard, xPOS, yPOS, photo_file):
        self.gameboard = gameboard
        self.photo1 = Image.open(photo_file)
        self.photo2 = ImageTk.PhotoImage(self.photo1)
        self.gameboard.create_image(xPOS, yPOS, image=self.photo2)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Well you're certainly right about one thing. I *am* using inheritance as a means of sharing information. I have updated my question (added an extra paragraph on bottom) in response to another commenters question. The reason why I have GamePiece inherit from GameBoard is because I don't want to have to worry about image transparency. Can you expand a little further on *why* sharing information between objects is not what inheritance is used for? I had thought that that was actually one of the **main** reasons for using it. To share information from one of object to another. Thanks. – Maz Apr 14 '20 at 16:20
  • @Maz: _"The reason why I have GamePiece inherit from GameBoard is because I don't want to have to worry about image transparency. "_ - inheritance won't solve that problem. – Bryan Oakley Apr 14 '20 at 17:15
  • Let me clarify that by transparency, I mean the background transparency. I'm not sure, but through my research, and according to another stack overflow answer, you won't have to worry about the background of an image not being transparent if you create the image on the same canvas as the gameboard. Let me see if I can find the exact stack overflow answer I found for that. – Maz Apr 14 '20 at 18:03
  • Here it is: https://stackoverflow.com/questions/53021603/how-to-make-a-tkinter-canvas-background-transparent – Maz Apr 14 '20 at 18:05
  • So, I figured by using inheritance, I could 'share information's with objects that are all basically on the same canvas, which would be the GameBoard – Maz Apr 14 '20 at 18:06
  • @Maz: my example shows creating an object on the same canvas. Maybe you missed that point? Notice how `GamePiece` uses `self.gameboard` to create the image. A gamepiece definitely is not the same as a gameboard, which is what inheritance would cause it to be. Instead, a gamepiece _uses_ a gameboard, which is passed in as a parameter when the piece is created. – Bryan Oakley Apr 14 '20 at 18:57
  • Oh! Okay, I understand now. Yeah I missed that, thank you for clarifying your point. – Maz Apr 14 '20 at 19:29