简体   繁体   English

Tkinter Label 未更新图像

[英]Tkinter Label not updating image


Im trying to make my first Tkinter project and decided on a Chess game.我正在尝试制作我的第一个 Tkinter 项目并决定进行国际象棋游戏。 Ive written most of the basic program but when I tried to execute the pre-programmed pawn movements the pawn images don't change even tho it seems like the module registers the movement.我已经编写了大部分基本程序,但是当我尝试执行预编程的典当移动时,即使看起来模块注册了移动,典当图像也不会改变。

Here is all the details:这是所有细节:

The widget structure is just one frame with label widgets placed in a grid representing a classical chess board.小部件结构只是一帧,其中 label 小部件放置在代表经典棋盘的网格中。

My program has two classes, boot and move.我的程序有两个类,引导和移动。 Both is called (instantiated?) directly.两者都被直接调用(实例化?)。 Boot creates the board layout and also the object called game containing two nested dictionaries game.pawns and game.squares. Boot 创建棋盘布局以及名为 game 的 object,其中包含两个嵌套字典 game.pawns 和 game.squares。

game.pawns游戏.pawns

game.pawns contains information about each pawn such as position ect and is reached like: game.pawns['B_Bishop_C']['pos'] where first letter is the color and the last letter is the horizontal starting position. game.pawns 包含有关每个 pawn 的信息,例如 position 等,并通过以下方式到达: game.pawns['B_Bishop_C']['pos'] 其中第一个字母是颜色,最后一个字母是水平起始 position。 More details about dictionary keys and values are the code (line 25) found in git.有关字典键和值的更多详细信息是 git 中的代码(第 25 行)。

game.squares游戏方块

game.squares contains information about the squares such as if it is occupied and by which pawn. game.squares 包含有关方格的信息,例如是否被占据以及被哪个棋子占据。 Also very importantly it contains the label widget with key ['wdgt'].同样非常重要的是,它包含带有键 ['wdgt'] 的 label 小部件。 Each square is reached with a string: '0 to 7' + 'A to H' so regular chess positioning but with one less index.每个方格都有一个字符串:'0 到 7' + 'A 到 H' 如此常规的国际象棋定位,但索引少了一个。 Ex Upper left '0A', down right '7H'.例如左上角'0A',右下角'7H'。

Ex: game.squares['0B']['widget'] would access the label widget where a black knight is standing (white at bottom).例如:game.squares['0B']['widget'] 将访问 label 小部件,其中有一个黑骑士站立(底部为白色)。

Problem问题

So back to the problem: For some reason when I try to.config the label to change the image it doesn't change even tho the imaged shows as it is added with the winfo command.回到问题上来:由于某种原因,当我尝试配置 label 以更改图像时,即使图像显示是使用 winfo 命令添加的,它也不会改变。

Code代码

Here is the code where called when I move a pawn to a empty square(where the error is)这是当我将棋子移动到空方格时调用的代码(错误所在)

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

Here is my GitHub:这是我的 GitHub:

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

Note:笔记:

Code from above is around line 250.上面的代码在第 250 行左右。

self.current_pawn is in same form as dict key for game.pawns self.current_pawn 与 game.pawns 的 dict 键形式相同

To run the code PIL and Tkitner is needed.运行代码需要 PIL 和 Tkitner。

Also pawns must be in the folder with the relative path given when creating the pawns at line 122-149此外,pawns 必须位于具有在第 122-149 行创建 pawn 时给出的相对路径的文件夹中

From line 300 and down is only pawn movement code.从第 300 行开始,只有典当移动代码。

There are probably some undiscoverd problems in the program程序中可能存在一些未发现的问题

Things I tried:我尝试过的事情:

Referencing image.参考图像。

Using image without alpha (transparency).使用没有 alpha 的图像(透明度)。

Tkinter Label does not show Image Tkinter Label 不显示图像

All help is appreciated.感谢所有帮助。

In your move function in line 315, you are reassigning the game.pawns dictionary with the new dictionary.在第 315 行的移动 function 中,您正在使用新字典重新分配game.pawns字典。 But the original dictionary is not being passed to that function!但是原始字典没有被传递给那个函数!

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

The game.pawns dictionary doesn't have the key of the pawn you are moving. game.pawns字典没有你正在移动的棋子的键。 Since you are reassigning the dict itself in this function, it would not work anyway.由于您要在此 function 中重新分配 dict 本身,因此无论如何它都不起作用。 You need to pass that dict along with the new position of your pawn:您需要将该 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)

Now the dict is passed along with the new position of your selected pawn:现在 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