为什么这些子类创建新的 tkinter 画布?
Why do these subclasses create new tkinter canvases?
我能够用更小的 50 行代码重现问题。这就是为什么您可能会看到看似 'useless' 需要参数和参数。
程序首先要做的是创建一个主 window 和游戏板对象,它是 tk.Canvas
的子class。该对象然后为每个 120x120 正方形创建 8 行和列,颜色交替。
然后,我创建游戏块(通常在 for 循环中完成,但这个 运行-down 示例只创建两个块)分别为它们提供 60x60 和 60x120 的位置。
最后,我用一个简单的退出按钮和 mainloop
功能将其包装起来。
我的代码似乎导致每次我尝试在板上放置一个图像项目时,在 GameBoard 上绘制一个新的 canvas。
现在,我 相信 这个错误源于 GameBoard class,特别是它调用 __init__
基础方法 class.
我已经尝试在所有不同的地方工作和修改以放置每个 self
方法,认为这可能会有所帮助,但无济于事。
但是,如果我注释掉创建 rook 和 pawn 的两行,则棋盘显示正常。所以我知道肯定是碎片直接造成的
所以,这是我对国际象棋游戏的尝试。请记住,它还远未完成,下面的代码不是我的代码的摘录,而是为了显示错误而完全重新制作的代码。
如果您看到任何与我的实际问题无关的明显问题,请知道我正在尽最大努力避免重复自己,并遵循 pip8 指南.因此,我们将不胜感激任何关于清洁度或整体功能的意见。
正如 quamrana 在评论中指出的那样:我从 GameBoard 继承 GamePiece 的原因是 特别是 因为我想 而不是 必须担心更改图像的背景以匹配所述图像所在 space 的颜色。
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()
继承意味着子class 是超class。如果您的 GamePiece 继承自 GameBoard,则 GamePiece 是一个 GameBoard。由于 GameBoard 创建了 canvas,GamePiece 也创建了
您似乎在使用继承来尝试在对象之间共享数据。这不是继承的目的。您的 GamePiece
class 不应继承自 GameBoard
。
您在创建 GamePiece 时正确地将 GameBoard 的实例作为第一个参数传递,因此您的 GamePiece 应该在棋盘上绘制自己时使用它。它应该看起来像这样:
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)
我能够用更小的 50 行代码重现问题。这就是为什么您可能会看到看似 'useless' 需要参数和参数。
程序首先要做的是创建一个主 window 和游戏板对象,它是 tk.Canvas
的子class。该对象然后为每个 120x120 正方形创建 8 行和列,颜色交替。
然后,我创建游戏块(通常在 for 循环中完成,但这个 运行-down 示例只创建两个块)分别为它们提供 60x60 和 60x120 的位置。
最后,我用一个简单的退出按钮和 mainloop
功能将其包装起来。
我的代码似乎导致每次我尝试在板上放置一个图像项目时,在 GameBoard 上绘制一个新的 canvas。
现在,我 相信 这个错误源于 GameBoard class,特别是它调用 __init__
基础方法 class.
我已经尝试在所有不同的地方工作和修改以放置每个 self
方法,认为这可能会有所帮助,但无济于事。
但是,如果我注释掉创建 rook 和 pawn 的两行,则棋盘显示正常。所以我知道肯定是碎片直接造成的
所以,这是我对国际象棋游戏的尝试。请记住,它还远未完成,下面的代码不是我的代码的摘录,而是为了显示错误而完全重新制作的代码。
如果您看到任何与我的实际问题无关的明显问题,请知道我正在尽最大努力避免重复自己,并遵循 pip8 指南.因此,我们将不胜感激任何关于清洁度或整体功能的意见。
正如 quamrana 在评论中指出的那样:我从 GameBoard 继承 GamePiece 的原因是 特别是 因为我想 而不是 必须担心更改图像的背景以匹配所述图像所在 space 的颜色。
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()
继承意味着子class 是超class。如果您的 GamePiece 继承自 GameBoard,则 GamePiece 是一个 GameBoard。由于 GameBoard 创建了 canvas,GamePiece 也创建了
您似乎在使用继承来尝试在对象之间共享数据。这不是继承的目的。您的 GamePiece
class 不应继承自 GameBoard
。
您在创建 GamePiece 时正确地将 GameBoard 的实例作为第一个参数传递,因此您的 GamePiece 应该在棋盘上绘制自己时使用它。它应该看起来像这样:
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)