Tkinter实现选中Listbox选项在frame_3中显示对应图片
预期运行效果

实现方案
核心逻辑是监听Listbox的选中事件,选中项变化时动态加载对应国旗图片更新显示区域,具体修改点如下:
- 移除代码中无用的
turtle库导入 frame_3区域只保留1个Label用于显示图片,无需提前创建多个Label、预加载所有国旗图片,减少内存占用- 给Listbox绑定
<<ListboxSelect>>事件,选中列表项时获取当前选中的大洲、国家名称,拼接对应国旗的文件路径加载图片 - 加载图片后必须将图片对象赋值为Label的属性,否则图片会被Python垃圾回收机制回收,导致显示区域空白
- 新增文件名映射字典,处理国旗文件名和列表显示的国家名不一致的情况(比如菲律宾国旗文件名为
PH.png,和列表显示名"Philippines"不匹配) - 切换大洲选项时清空原有显示的图片,避免残留上一大洲的图片内容
完整修改后代码
from tkinter import * from PIL import Image, ImageTk root = Tk() root.title("LT_DelosSantosCristianJay") root.geometry("500x200") # 国旗文件名映射,处理文件名与国家显示名不匹配的场景 file_name_map = { "Philippines": "PH.png" # 后续新增国家如果文件名不匹配,直接在该字典中添加对应关系即可 } # 区域划分 frame_1 = Frame(root) frame_1.grid(row = 0, column = 0, columnspan = 2) frame_2 = Frame(root) frame_2.grid(row = 1, column = 0,pady=(0,20)) frame_3 = Frame(root) frame_3.grid(row = 1, column = 1) continents = { "Asia": ["Philippines", "Malaysia", "Taiwan", "Singapore", "Thailand", "India"], "Africa": ["Algeria", "Angola", "Egypt", "Cape Verde", "Liberia", "Kenya", "Morocco", "Nigeria"], "America": ["Venezuela", "Peru", "Jamaica", "United States", "Cuba", "Chile", "Argentina"], "Europe": ["Russia", "Germany", "United Kingdom", "Italy", "Ukraine", "France", "Belgium"] } # 顶部大洲单选栏 var = StringVar() var.set('Select') Radiobutton(frame_1, text="Asia", font=("Times", 12, "bold"), fg="blue", variable=var, value='Asia', borderwidth=1, relief=SOLID, width=10, command=lambda: RadioSelected(var.get())).pack(side=LEFT) Radiobutton(frame_1, text="Africa", font=("Times", 12, "bold"), fg="blue", variable=var, value="Africa", borderwidth=1, relief=SOLID, width=11, command=lambda: RadioSelected(var.get())).pack(side=LEFT) Radiobutton(frame_1, text="America", font=("Times", 12, "bold"), fg="blue", variable=var, value="America", borderwidth=1, relief=SOLID, width=11, command=lambda: RadioSelected(var.get())).pack(side=LEFT) Radiobutton(frame_1, text="Europe", font=("Times", 12, "bold"), fg="blue", variable=var, value="Europe", borderwidth=1, relief=SOLID, width=11, command=lambda: RadioSelected(var.get())).pack(side=LEFT) # 左侧国家列表 flag_listbox = Listbox(frame_2, font=("Times",15,"bold"),width=15,height=7) flag_listbox.pack(side=LEFT, fill=BOTH) flag_scrollbar = Scrollbar(frame_2) flag_scrollbar.pack(side=RIGHT, fill=BOTH) flag_listbox.config(yscrollcommand=flag_scrollbar.set) flag_scrollbar.config(command=flag_listbox.yview) # 列表选中回调:切换对应国旗 def OnListSelect(event): # 无选中项时直接返回,避免报错 if not flag_listbox.curselection(): return select_index = flag_listbox.curselection()[0] select_country = flag_listbox.get(select_index) current_continent = var.get() # 拼接图片完整路径 img_file = file_name_map.get(select_country, f"{select_country}.png") img_path = f"{current_continent}/{img_file}" # 加载图片并调整尺寸适配显示区域 img = Image.open(img_path).resize((320,150), Image.Resampling.LANCZOS) current_flag = ImageTk.PhotoImage(img) # 更新显示内容,绑定图片对象到Label属性防止被垃圾回收 flag_label.config(image=current_flag) flag_label.image = current_flag # 绑定列表选中事件 flag_listbox.bind("<<ListboxSelect>>", OnListSelect) # 大洲单选切换回调:更新列表内容 def RadioSelected(Value): flag_listbox.delete(0, END) list_values = continents[Value] for i in list_values: flag_listbox.insert(END, i) # 切换大洲时清空原有图片 flag_label.config(image='') flag_label.image = None # 右侧图片显示区域 flag_label = Label(frame_3,bg="white",width=320,height=150) flag_label.grid(sticky="we",pady=(0,20)) root.mainloop()
注意:请确保你的国旗图片路径和代码中拼接的路径一致,比如亚洲国家的国旗都放在代码同级目录下的
Asia文件夹中,其他大洲同理,否则会报文件找不到的错误。
内容的提问来源于stack exchange,提问作者Jay Delos Santos
相关产品推荐
相关产品推荐

