You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter图片预览App移除按钮Bug修复:移除后图片显示异常

修复Tkinter图片预览应用的移除功能Bug

问题背景

我开发了一款用于预览文件夹中图片的Tkinter应用,文件夹包含bicycle、car、plane、ship四张图片。应用设有添加和移除按钮,图片预览前需先缩放到指定尺寸。添加功能运行正常,但移除功能存在Bug,无法正确显示移除后的图片。

原代码

import random
from tkinter import *
from PIL import ImageTk, Image 

upper = Toplevel()
upper.title('New Session')
upper.geometry('800x720')
upper.config(bg="#d7dae2")
upper.resizable(False, False)

values = ['bicycle', 'car', 'plane', 'ship']
deck = []
player = []

for card in values:
    deck.append(f'{card}')

def resize_cards(card):
    global our_card_image
    our_card_img = Image.open(card)
    our_card_resize_image = our_card_img.resize((130, 130))
    our_card_image = ImageTk.PhotoImage(our_card_resize_image)
    return our_card_image
   
def add():
    global player_image, our_card_image, card
    try:
        card = random.choice(deck)
       
        # Remove the card from deck
        deck.remove(card)
        # Append card to player list
        player.append(card)
        
        print(player)
        
        player_image = resize_cards(f'How Tkinter - Learning App\\images\\{card}.png')
        player_label.config(image=player_image)
  
        
        hex.config(text=f'{len(player)}/{len(values)}')
    except:
        hex.config(text=0)

def remove():
    global player_label, player_image
    try:
        deck.append(card)
        player.pop()   

        player_image = resize_cards(f'How Tkinter - Learning App\\images\\{card}.png')
        player_label.config(image=player_image)
        hex.config(text=f'{len(player)}/{len(values)}')
    except:
        hex.config(text=f'{len(player)}/{len(values)}')

session_frame = Frame(upper)
session_frame.place(x=20, y=40)
       
player_label = Label(session_frame, image='', bg='white')
player_label.pack(padx=10, ipady=10, side=RIGHT)

plus = Button(upper, text='   +   ',
                   font=('Helvatica', 12, 'bold'), command=add)
plus.place(x=760, y=0)
    
minus = Button(upper, text='   -   ',
                    font=('Helvatica', 12, 'bold'), command=remove)
minus.place(x=760, y=35)
    
hex = Label(upper, text=' #/# ', height= 2,
                  font=('Helvatica', 12, 'bold'))
hex.place(x=760, y=70)

root.mainloop()

问题现象

  • 点击添加按钮,终端显示['bicycle'],图片显示自行车;
  • 再次点击添加按钮,终端显示['bicycle', 'car'],图片显示汽车;
  • 点击移除按钮(移除汽车图片),终端显示['bicycle'],但图片仍显示汽车而非自行车。

修复方案

Bug根源在于remove函数中使用的card变量是上一次添加操作的全局残留值,移除后没有更新为player列表当前的最后一个元素。正确逻辑应该是:移除后如果player列表不为空,就加载列表最后一项的图片;如果为空,则清空标签图片。

修改后的完整代码

import random
from tkinter import *
from PIL import ImageTk, Image 

upper = Toplevel()
upper.title('New Session')
upper.geometry('800x720')
upper.config(bg="#d7dae2")
upper.resizable(False, False)

values = ['bicycle', 'car', 'plane', 'ship']
deck = []
player = []

for card in values:
    deck.append(f'{card}')

def resize_cards(card):
    global our_card_image
    our_card_img = Image.open(card)
    our_card_resize_image = our_card_img.resize((130, 130))
    our_card_image = ImageTk.PhotoImage(our_card_resize_image)
    return our_card_image
   
def add():
    global player_image, our_card_image, card
    try:
        card = random.choice(deck)
       
        deck.remove(card)
        player.append(card)
        
        print(player)
        
        player_image = resize_cards(f'How Tkinter - Learning App\\images\\{card}.png')
        player_label.config(image=player_image)
  
        hex.config(text=f'{len(player)}/{len(values)}')
    except:
        hex.config(text=0)

def remove():
    global player_label, player_image
    try:
        # 先取出要移除的元素,再放回deck
        removed_card = player.pop()
        deck.append(removed_card)
        
        # 根据player列表是否为空更新图片
        if player:
            last_card = player[-1]
            player_image = resize_cards(f'How Tkinter - Learning App\\images\\{last_card}.png')
            player_label.config(image=player_image)
        else:
            player_label.config(image='')
            
        hex.config(text=f'{len(player)}/{len(values)}')
    except:
        hex.config(text=f'{len(player)}/{len(values)}')

session_frame = Frame(upper)
session_frame.place(x=20, y=40)
       
player_label = Label(session_frame, image='', bg='white')
player_label.pack(padx=10, ipady=10, side=RIGHT)

plus = Button(upper, text='   +   ',
                   font=('Helvatica', 12, 'bold'), command=add)
plus.place(x=760, y=0)
    
minus = Button(upper, text='   -   ',
                    font=('Helvatica', 12, 'bold'), command=remove)
minus.place(x=760, y=35)
    
hex = Label(upper, text=' #/# ', height= 2,
                  font=('Helvatica', 12, 'bold'))
hex.place(x=760, y=70)

root.mainloop()

关键修改点

  1. 在remove函数中,通过removed_card = player.pop()获取被移除的元素,再将其放回deck,彻底摆脱对全局card变量的依赖;
  2. 移除后检查player列表状态:
    • 列表不为空时,取最后一个元素player[-1]加载并显示对应图片;
    • 列表为空时,清空player_label的图片;
  3. 所有操作均基于player列表的实际状态,避免全局变量残留值导致的错误。

内容的提问来源于stack exchange,提问作者Kelvin Loh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:25:20