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

Python Tkinter读取Oracle BLOB字段显示图片的实现方法

问题背景

通过Python读取Oracle表数据填充Tkinter界面控件时,表中BLOB类型的员工照片字段无法正常加载展示,目前EMPLOYEE_ID、FIRST_NAME两个文本字段已可正常读取填充,原实现代码如下:

import cx_Oracle
from tkinter import *


root = Tk()

con = cx_Oracle.connect('hr/hr@localhost/orcl')

cur = con.cursor()

cur.execute("SELECT EMPLOYEE_ID, FIRST_NAME, photo FROM HR.EMP WHERE EMPLOYEE_ID = 3000")

row = cur.fetchone()
print(cur.rowcount)
if cur.rowcount > 0:
    print('Row retrieved successfully.')

else:
    print('Data Retrieval failed.')

photo = image_types()
EMPLOYEE_ID = NUMERIC
FIRST_NAME = StringVar
cursor = con.cursor()

employee_id_entry = Entry(textvariable=EMPLOYEE_ID, width="30", background='BLUE')
first_name_entry = Entry(textvariable=FIRST_NAME, width="30", background='YELLOW')
photo_entry = Entry(textvariable=photo, width="30", background='GREEN')

employee_id_entry.place(x=10, y=10)
first_name_entry.place(x=10, y=30)
photo_entry.place(x=10, y=50)
employee_id_entry.insert(0, row[0])
first_name_entry.insert(0, row[1])
# photo_entry.insert(END, row[2])


cursor.close()
con.close()

root.mainloop()
现存问题
  • 误用Entry文本输入框承载图片:Entry仅支持文本内容展示,无法渲染图片,需要使用Label控件作为图片载体
  • BLOB数据未做格式转换:Oracle读取到的BLOB字段是原始二进制流,Tkinter无法直接识别,需要通过图片处理库转换为兼容的图片对象
  • 存在大量无效定义:原代码中image_types()、NUMERIC为不存在的方法/类型,StringVar未做实例化,重复创建多余cursor,都会直接触发运行错误
  • 未处理Tkinter图片回收机制:Tkinter图片对象若无持久引用会被垃圾回收机制自动回收,导致图片显示空白
解决步骤
  • 安装依赖库:除cx_Oracle和Tkinter外,需要安装Pillow处理图片二进制流,执行安装命令pip install pillow
  • 读取BLOB二进制内容:调用BLOB对象的read()方法拿到完整图片二进制数据,通过内存字节流对象承载,无需写入本地磁盘
  • 转换图片格式:用Pillow加载内存中的二进制图片,转为Tkinter可识别的ImageTk.PhotoImage对象
  • 绑定图片引用:将转换后的图片对象绑定到展示控件的属性上,避免被垃圾回收
  • 清理原代码中的无效变量和冗余逻辑
修正后完整代码
import cx_Oracle
from tkinter import *
from PIL import Image, ImageTk
from io import BytesIO

root = Tk()
root.geometry("350x250") # 适配控件和图片尺寸调整窗口大小

# 数据库连接和查询
con = cx_Oracle.connect('hr/hr@localhost/orcl')
cur = con.cursor()
cur.execute("SELECT EMPLOYEE_ID, FIRST_NAME, photo FROM HR.EMP WHERE EMPLOYEE_ID = 3000")
row = cur.fetchone()

# 文本字段填充
employee_id_entry = Entry(width=30, background='BLUE')
first_name_entry = Entry(width=30, background='YELLOW')
employee_id_entry.place(x=10, y=10)
first_name_entry.place(x=10, y=30)

if row:
    employee_id_entry.insert(0, row[0])
    first_name_entry.insert(0, row[1])
    
    # 处理BLOB图片
    blob_data = row[2].read() # 读取BLOB二进制内容
    image_stream = BytesIO(blob_data) # 转内存字节流
    pil_image = Image.open(image_stream)
    # 可根据需要调整图片尺寸,例:缩放到宽120高150
    pil_image = pil_image.resize((120, 150), Image.Resampling.LANCZOS)
    tk_photo = ImageTk.PhotoImage(pil_image)
    
    # 用Label展示图片
    photo_label = Label(root, image=tk_photo)
    photo_label.image = tk_photo # 绑定引用防止被GC回收
    photo_label.place(x=10, y=70)

# 关闭数据库连接
cur.close()
con.close()

root.mainloop()

注意:如果BLOB中存储的图片格式不是Pillow支持的通用格式(jpg/png等),需要先对应做格式解码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:36:14