python canvas 循环创建图像
python canvas create image in loop
你好,我最近开始学习 tkinter 并决定学习棋盘游戏。
下面是我的代码:
import tkinter as tk
class GameBoard(tk.Frame):
def __init__(self, parent, rows=8, columns=8, size=70, color1="white", color2="blue"):
'''size is the size of a square, in pixels'''
self.rows = rows
self.columns = columns
self.size = size
self.color1 = color1
self.color2 = color2
self.pieces = {}
canvas_width = columns * size
canvas_height = rows * size
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,
width=canvas_width, height=canvas_height, background="bisque")
self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2)
root = tk.Tk()
board = GameBoard(root)
board.pack(side="top", fill="both", expand="true", padx=4, pady=4)
black_rook_l = tk.PhotoImage(file=black_rook_img)
black_rook_l = black_rook_l.subsample(2, 2)
board.addpiece("black_rook_l", black_rook_l, 0,0)
上面的代码我是将棋子(黑车)添加到棋盘上,这是按预期工作的。
下面是辅助函数:
def addpiece(self, name, image, row=0, column=0):
'''Add a piece to the playing board'''
self.canvas.create_image(0,0, image=image, tags=(name, "piece"), anchor="c")
self.placepiece(name, row, column)
def placepiece(self, name, row, column):
'''Place a piece at the given row/column'''
self.pieces[name] = (row, column)
x0 = (column * self.size) + int(self.size/2)
y0 = (row * self.size) + int(self.size/2)
# print(name, x0, y0)
self.canvas.coords(name, x0, y0)
但是当我尝试在 for 循环的帮助下放置棋子时出现问题。
下面是代码:
for i in range(8):
bname = tk.PhotoImage(file=black_pawn_img)
bname = bname.subsample(2, 2)
board.addpiece("black_pawn_"+str(i), bname, 1,i)
root.mainloop()
它只放置最后一个棋子。
请suggest/help我理解这个问题。
提前致谢。
python 图像对象正在被垃圾收集器销毁。您需要保存对图像的引用。第一次通过循环时,bname
持有对创建的第一个图像的引用。在下一次迭代中,bname
被修改为引用第二张图像。因此,第一张图片不再有参考。
一种简单的方法是在创建它们的代码块中跟踪它们:
images = []
for i in range(8):
bname = tk.PhotoImage(file=black_pawn_img)
bname = bname.subsample(2, 2)
board.addpiece("black_pawn_"+str(i), bname, 1,i)
images.append(bname)
另一种方法是 addpiece
保存它们:
class GameBoard(...):
def __init__(...):
...
self.images = []
...
def addpiece(self, name, image, row=0, column=0):
...
self.images.append(image)
...
你好,我最近开始学习 tkinter 并决定学习棋盘游戏。
下面是我的代码:
import tkinter as tk
class GameBoard(tk.Frame):
def __init__(self, parent, rows=8, columns=8, size=70, color1="white", color2="blue"):
'''size is the size of a square, in pixels'''
self.rows = rows
self.columns = columns
self.size = size
self.color1 = color1
self.color2 = color2
self.pieces = {}
canvas_width = columns * size
canvas_height = rows * size
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,
width=canvas_width, height=canvas_height, background="bisque")
self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2)
root = tk.Tk()
board = GameBoard(root)
board.pack(side="top", fill="both", expand="true", padx=4, pady=4)
black_rook_l = tk.PhotoImage(file=black_rook_img)
black_rook_l = black_rook_l.subsample(2, 2)
board.addpiece("black_rook_l", black_rook_l, 0,0)
上面的代码我是将棋子(黑车)添加到棋盘上,这是按预期工作的。
下面是辅助函数:
def addpiece(self, name, image, row=0, column=0):
'''Add a piece to the playing board'''
self.canvas.create_image(0,0, image=image, tags=(name, "piece"), anchor="c")
self.placepiece(name, row, column)
def placepiece(self, name, row, column):
'''Place a piece at the given row/column'''
self.pieces[name] = (row, column)
x0 = (column * self.size) + int(self.size/2)
y0 = (row * self.size) + int(self.size/2)
# print(name, x0, y0)
self.canvas.coords(name, x0, y0)
但是当我尝试在 for 循环的帮助下放置棋子时出现问题。 下面是代码:
for i in range(8):
bname = tk.PhotoImage(file=black_pawn_img)
bname = bname.subsample(2, 2)
board.addpiece("black_pawn_"+str(i), bname, 1,i)
root.mainloop()
它只放置最后一个棋子。
请suggest/help我理解这个问题。
提前致谢。
python 图像对象正在被垃圾收集器销毁。您需要保存对图像的引用。第一次通过循环时,bname
持有对创建的第一个图像的引用。在下一次迭代中,bname
被修改为引用第二张图像。因此,第一张图片不再有参考。
一种简单的方法是在创建它们的代码块中跟踪它们:
images = []
for i in range(8):
bname = tk.PhotoImage(file=black_pawn_img)
bname = bname.subsample(2, 2)
board.addpiece("black_pawn_"+str(i), bname, 1,i)
images.append(bname)
另一种方法是 addpiece
保存它们:
class GameBoard(...):
def __init__(...):
...
self.images = []
...
def addpiece(self, name, image, row=0, column=0):
...
self.images.append(image)
...