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

如何在Tkinter中通过for循环展示DataFrame中的字节形式图片?

解决Tkinter循环展示DataFrame中字节图片仅显示最后一张的问题

问题核心原因

  1. Tkinter的ImageTk.PhotoImage对象若无持久引用,会被Python垃圾回收机制回收,仅最后一张图片能保留。
  2. 原代码表头创建逻辑放在循环内,会重复生成表头覆盖之前内容。
  3. 图片Label的image参数错误使用str.encode()处理图片对象,导致无法正确识别图片。

修复步骤

  • 将表头创建移出循环:遍历DataFrame前一次性创建所有表头标签,避免重复覆盖。
  • 正确传入图片对象:直接将ImageTk.PhotoImage实例赋值给Label的image参数,无需额外编码。
  • 保留图片引用:将每个图片对象绑定到对应Label实例(如pic.image = img),或存入列表维持引用,防止被回收。
  • 修正其他逻辑错误:搜索窗口改用Toplevel()而非Tk(),搜索时获取输入框内容需调用.get(),引用正确的DataFrame变量df_main。

修正后的完整代码

import pandas as pd
from PIL import ImageTk, Image
from tkinter import *
import tkinter as tk
from tkinter import filedialog
import base64
import io

df_main = pd.read_csv("C:/Users/noahk/Documents/Trial.csv")

root = Tk()
root.title("Fabric Database")
root.geometry("400x400")

def upload_file():
    global lol
    file = filedialog.askopenfilename()
    converted_string = base64.b64encode(open(file, "rb").read())
    lol = converted_string.decode("utf-8")

def submit():
    global df_main
    new_row = {
        'Name': name.get(),
        'Country': country.get(),
        'Price': price.get(),
        'Thickness': thickness.get(),
        'Fabric Example': lol
    }
    df_main = pd.concat([df_main, pd.DataFrame([new_row])], ignore_index=True)
    print(df_main)

def show_pic():
    global img, table
    b = base64.b64decode(lol)
    img = Image.open(io.BytesIO(b))
    img = img.resize((20, 20), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(img)
    pic = Label(table, image=img)
    pic.image = img  # 保留引用防止回收
    pic.grid(row=1, column=5)
   
def show_table():
    global table
    table = Toplevel()
    table.title("Fabric Database")
    table.geometry("600x400")  # 加宽窗口适配列数
    
    # 一次性创建表头
    headers = ["Name", "Country", "Price", "Thickness", "Fabric Example"]
    for col, header in enumerate(headers):
        Label(table, text=header).grid(row=0, column=col, padx=5, pady=5)
    
    img_list = []
    for x in range(df_main.shape[0]):
        # 解码并处理图片
        b = base64.b64decode(df_main["Fabric Example"][x])
        img = Image.open(io.BytesIO(b))
        img = img.resize((20, 20), Image.ANTIALIAS)
        img = ImageTk.PhotoImage(img)
        img_list.append(img)
        
        # 显示文本数据
        Label(table, text=df_main["Name"][x]).grid(row=x+1, column=0, padx=5, pady=2)
        Label(table, text=df_main["Country"][x]).grid(row=x+1, column=1, padx=5, pady=2)
        Label(table, text=df_main["Price"][x]).grid(row=x+1, column=2, padx=5, pady=2)
        Label(table, text=df_main["Thickness"][x]).grid(row=x+1, column=3, padx=5, pady=2)
        
        # 显示图片并保留引用
        pic = Label(table, image=img)
        pic.image = img  # 绑定引用防止回收
        pic.grid(row=x+1, column=4, padx=5, pady=2)
    
def search():
    search = Toplevel()  # 改用Toplevel避免多主窗口
    search.title("Fabric Database")
    search.geometry("600x300")
    
    # 创建搜索输入框和标签
    headers = ["Name", "Country", "Price", "Thickness", "Fabric Example"]
    entries = {}
    for col, header in enumerate(headers):
        Label(search, text=header).grid(row=0, column=col, padx=5)
        entry = Entry(search, width=15)
        entry.grid(row=1, column=col, padx=5)
        entries[header] = entry
    
    def search_table():
        # 构建查询条件
        query = pd.Series([True]*len(df_main))
        for header in headers:
            val = entries[header].get()
            if val:
                query &= (df_main[header] == val)
        # 显示结果
        result_df = df_main[query]
        # 用文本框显示结果
        result_text = Text(search, height=10, width=80)
        result_text.grid(row=3, column=0, columnspan=5, padx=5, pady=10)
        result_text.insert(END, result_df.to_string())
    
    Button(search, text="Search", command=search_table).grid(row=2, column=0, columnspan=5, pady=10, ipadx=100)

# 主窗口输入控件
name = Entry(root, width=30)
name.grid(row=0, column=1, padx=20, pady=(10,0))
country = Entry(root, width=30)
country.grid(row=1, column=1)
price = Entry(root, width=30)
price.grid(row=2, column=1)
thickness = Entry(root, width=30)
thickness.grid(row=3, column=1)
fabric_example = tk.Button(root, text='Upload Files', width=20, command=upload_file)
fabric_example.grid(row=4, column=1)

# 主窗口标签
Label(root, text="Name").grid(row=0, column=0, pady=(10,0))
Label(root, text="Country").grid(row=1, column=0)
Label(root, text="Price").grid(row=2, column=0)
Label(root, text="Thickness").grid(row=3, column=0)
Label(root, text="Fabric example").grid(row=4, column=0)

# 主窗口按钮
submit_btn = Button(root, text="Add to Database", command=submit)
submit_btn.grid(row=5, column=0, columnspan=2, pady=10, padx=10, ipadx=105)

show_btn = Button(root, text="Press", command=show_pic)
show_btn.grid(row=7, column=2)

query_btn = Button(root, text="Show Table", command=show_table)
query_btn.grid(row=7, column=0, columnspan=2, pady=10, padx=10, ipadx=120)

search_btn = Button(root, text="Search Databank", command=search)
search_btn.grid(row=12, column=0, columnspan=2, pady=10, padx=10, ipadx=120)

root.mainloop()

内容的提问来源于stack exchange,提问作者Imperfected Gaming

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:25:21