Python 为什么这些子类创建新的tkinter画布?

Python 为什么这些子类创建新的tkinter画布?,python,class,canvas,tkinter,init,Python,Class,Canvas,Tkinter,Init,我能够用一个小得多的50行代码重新创建这个问题。这就是为什么您可能会看到对参数和参数的“无用”需求 该程序首先要做的是创建一个主窗口和gameboard对象,它是tk.Canvas的一个子类。然后,该对象为每个120x120正方形创建8行和8列交替颜色 然后,我创建了游戏块,通常会在for循环中完成,但这个简单的示例只创建了两个块,分别为60x60和60x120 最后,我用一个简单的退出按钮和mainloop函数来结束它 每次我试图在游戏板上放置一个图像项目时,我的代码似乎都会导致在游戏板上绘制

我能够用一个小得多的50行代码重新创建这个问题。这就是为什么您可能会看到对参数和参数的“无用”需求

该程序首先要做的是创建一个主窗口和gameboard对象,它是tk.Canvas的一个子类。然后,该对象为每个120x120正方形创建8行和8列交替颜色

然后,我创建了游戏块,通常会在for循环中完成,但这个简单的示例只创建了两个块,分别为60x60和60x120

最后,我用一个简单的退出按钮和mainloop函数来结束它

每次我试图在游戏板上放置一个图像项目时,我的代码似乎都会导致在游戏板上绘制一个新画布

现在,我相信这个错误源于GameBoard类,特别是它从基类调用_uinit__u方法的地方

我试着在所有不同的地方工作和改造,让每个自我方法都认为这可能会有所帮助,但没有效果

但是,如果我注释掉我创建rook和pawn的两行,那么棋盘看起来很正常。所以我知道这一定是由碎片直接造成的

这是我下国际象棋的尝试。请记住,它还远没有完成,下面的代码不是我代码的摘录,而是为了显示错误而进行的一次彻底的重新创作

如果您看到任何与我的实际问题无关的突出问题,请知道我正在尽最大努力避免重复自己,并遵循pip8准则。因此,任何关于清洁度或整体功能的意见都将受到极大的赞赏

正如quamrana在评论中指出的那样:我之所以让GamePiece继承GameBoard,是因为我不想担心改变图像的背景以匹配图像所在空间的颜色

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()

继承意味着子类是超类。如果您的游戏件继承自GameBoard,那么GameBoard就是一个GameBoard。由于GameBoard创建了一个画布,Gamepoice也创建了一个画布

您似乎正在使用继承来尝试在对象之间共享数据。这不是继承的目的。您的GamePiece类不应从GameBoard继承

创建游戏件时,您正确地将GameBoard实例作为第一个参数传入,因此您的游戏件在板上绘制自身时应使用该参数。它应该看起来像这样:

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)

为什么GameBoard会继承GameBoard?这是个好问题。我从GameBoard继承了GamePiece,因为我不想担心改变图像的背景以适应所说的图像所在的任何颜色空间。我将在实际问题中更新这一点。好吧,有一件事你肯定是对的。我使用继承作为共享信息的一种手段。我已经更新了我的问题,在底部添加了一个额外的段落,以回应另一个评论者的问题。我之所以要从GameBoard继承GamePiece,是因为我不想担心图像的透明度。您能否进一步阐述一下为什么在对象之间共享信息不是继承的用途?我认为这实际上是使用它的主要原因之一。从一个对象到另一个对象共享信息。谢谢。@Maz:我之所以从GameBoard继承Gamepoice,是因为我不想担心图像的透明度。-继承并不能解决这个问题。让我澄清一下,所谓透明度,我指的是背景透明度。我不确定,但通过我的研究,根据另一个堆栈溢出的答案,如果你在与游戏板相同的画布上创建图像,你就不必担心图像的背景不透明。让我看看我是否能找到我找到的关于堆栈溢出的确切答案。这里是:因此,我认为通过使用继承,我可以与基本上都在同一画布上的对象共享信息,这将是游戏板