[英]Tkinter Label not updating image
我正在尝试制作我的第一个 Tkinter 项目并决定进行国际象棋游戏。 我已经编写了大部分基本程序,但是当我尝试执行预编程的典当移动时,即使看起来模块注册了移动,典当图像也不会改变。
小部件结构只是一帧,其中 label 小部件放置在代表经典棋盘的网格中。
我的程序有两个类,引导和移动。 两者都被直接调用(实例化?)。 Boot 创建棋盘布局以及名为 game 的 object,其中包含两个嵌套字典 game.pawns 和 game.squares。
game.pawns 包含有关每个 pawn 的信息,例如 position 等,并通过以下方式到达: game.pawns['B_Bishop_C']['pos'] 其中第一个字母是颜色,最后一个字母是水平起始 position。 有关字典键和值的更多详细信息是 git 中的代码(第 25 行)。
game.squares 包含有关方格的信息,例如是否被占据以及被哪个棋子占据。 同样非常重要的是,它包含带有键 ['wdgt'] 的 label 小部件。 每个方格都有一个字符串:'0 到 7' + 'A 到 H' 如此常规的国际象棋定位,但索引少了一个。 例如左上角'0A',右下角'7H'。
例如:game.squares['0B']['widget'] 将访问 label 小部件,其中有一个黑骑士站立(底部为白色)。
回到问题上来:由于某种原因,当我尝试配置 label 以更改图像时,即使图像显示是使用 winfo 命令添加的,它也不会改变。
这是当我将棋子移动到空方格时调用的代码(错误所在)
img = game.pawns[self.current_pawn]['img']
game.squares[pos]['wdgt'].image = img
game.squares[pos]['wdgt'].config(image=img)
#replace image of target square to the new pawn
game.squares[game.pawns[self.current_pawn]['pos']]['occ'] = None
#Changes occ of old square
game.pawns[self.current_pawn]['pos'] = pos
#changes moving pawn attribute position to new
game.squares[game.pawns[self.current_pawn]['pos']]['wdgt'].config(image = '')
#remvoes pawn from old square
game.squares[pos]['occ'] = pawn
#Changes occ of new square
https://gits-15.sys.kth.se/markusjs/Chess
上面的代码在第 250 行左右。
self.current_pawn 与 game.pawns 的 dict 键形式相同
运行代码需要 PIL 和 Tkitner。
此外,pawns 必须位于具有在第 122-149 行创建 pawn 时给出的相对路径的文件夹中
从第 300 行开始,只有典当移动代码。
程序中可能存在一些未发现的问题
参考图像。
使用没有 alpha 的图像(透明度)。
感谢所有帮助。
在第 315 行的移动 function 中,您正在使用新字典重新分配game.pawns
字典。 但是原始字典没有被传递给那个函数!
def move(self, event):
if self.is_white:
pawn = 'W_' + self.current_pawn[1:] # piece of current player color (whites or blacks)
else:
pawn = 'B_' + self.current_pawn[1:]
pos = str(self.row) + chr(self.col + ord('A')) #position of the square
# Save the current selected pawn in a variable to pass it to aftermove (with its new position) method
img = game.pawns[self.current_pawn]['img'] #image of moving pawn is saved on attribute img
game.squares[pos]['wdgt'].image = img #widget reference as key ('0B') and then attribute image from widget (tkinter label). No change done to image on widget
game.squares[pos]['wdgt'].config(image=img) #config widget gets image from attribute
game.squares[game.pawns[self.current_pawn]['pos']]['occ'] = None #square where the pawn is currently on gets empty occ (None)
game.pawns[self.current_pawn]['pos'] = pos #dict key for moving pawn gets new position (position of new square)
game.squares[game.pawns[self.current_pawn]['pos']]['wdgt'].config(image = '') #config widget on label of new square and get rid of image
game.pawns
字典没有你正在移动的棋子的键。 由于您要在此 function 中重新分配 dict 本身,因此无论如何它都不起作用。 您需要将该 dict 与您的pawn 的新 position 一起传递:
def move(self, event):
if self.is_white:
pawn = 'W_' + self.current_pawn[1:] # piece of current player color (whites or blacks)
else:
pawn = 'B_' + self.current_pawn[1:]
pos = str(self.row) + chr(self.col + ord('A')) #position of the square
# Save the current selected pawn in a variable to pass it to aftermove (with its new position) method
img = game.pawns[self.current_pawn]['img'] #image of moving pawn is saved on attribute img
game.squares[pos]['wdgt'].image = img #widget reference as key ('0B') and then attribute image from widget (tkinter label). No change done to image on widget
game.squares[pos]['wdgt'].config(image=img) #config widget gets image from attribute
game.squares[game.pawns[self.current_pawn]['pos']]['occ'] = None #square where the pawn is currently on gets empty occ (None)
temp = game.pawns #dict dictionary object holding all pawn info such as position ect gets saved in temp
game.pawns[self.current_pawn]['pos'] = pos #dict key for moving pawn gets new position (position of new square)
game.squares[game.pawns[self.current_pawn]['pos']]['wdgt'].config(image = '') #config widget on label of new square and get rid of image
aftermove(temp, pawn, pos)
现在 dict 与您选择的 pawn 的新 position 一起传递:
def aftermove(dict, piece, pos): #takes dict with piece and its old position as input and the targets postion as a string 'A1'
if self.is_white:
pawn = 'W_' + self.current_pawn[1:] # piece of current player color (whites or blacks)
else:
pawn = 'B_' + self.current_pawn[1:]
game.squares[game.pawns[self.current_pawn]['pos']]['occ'] = None #square where the pawn is currently on gets empty occ (None)
temp = game.pawns #dict dictionary object holding all pawn info such as position ect gets saved in temp
game.pawns[self.current_pawn]['pos'] = pos #dict key for moving pawn gets new position (position of new square)
game.squares[game.pawns[self.current_pawn]['pos']]['wdgt'].config(image = '') #config widget on label of new square and get rid of image
aftermove(temp, pawn, pos) #after move function itself called again to retrace steps until no more pieces left to move hence no more recursion needed
return #return to stop recursion looping which causes program to crash when it reaches the maximum recursion depth limit for the amount of pawns there are.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.