繁体   English   中英

Tkinter Label 未更新图像

[英]Tkinter Label not updating image


我正在尝试制作我的第一个 Tkinter 项目并决定进行国际象棋游戏。 我已经编写了大部分基本程序,但是当我尝试执行预编程的典当移动时,即使看起来模块注册了移动,典当图像也不会改变。

这是所有细节:

小部件结构只是一帧,其中 label 小部件放置在代表经典棋盘的网格中。

我的程序有两个类,引导和移动。 两者都被直接调用(实例化?)。 Boot 创建棋盘布局以及名为 game 的 object,其中包含两个嵌套字典 game.pawns 和 game.squares。

游戏.pawns

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

这是我的 GitHub:

https://gits-15.sys.kth.se/markusjs/Chess

笔记:

上面的代码在第 250 行左右。

self.current_pawn 与 game.pawns 的 dict 键形式相同

运行代码需要 PIL 和 Tkitner。

此外,pawns 必须位于具有在第 122-149 行创建 pawn 时给出的相对路径的文件夹中

从第 300 行开始,只有典当移动代码。

程序中可能存在一些未发现的问题

我尝试过的事情:

参考图像。

使用没有 alpha 的图像(透明度)。

Tkinter Label 不显示图像

感谢所有帮助。

在第 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM