如何在Custom Tkinter文本框中插入图片?解密程序GUI开发求助
在Custom Tkinter文本框中插入解密后的图片
我正在开发一款解密文件加密数据的程序,要求解密后的数据只能在程序内查看。用Custom Tkinter构建GUI界面,目前遇到技术难题:希望程序能够显示图片,但不知如何将解密后的数据(图片字节)插入到Tkinter文本框中。以下是数据窗口的代码:
import sys import platform import os from cryptography.fernet import Fernet from customtkinter import * from CTkListbox import * global PLATFORM PLATFORM = platform.system() with open('bin/main_path.txt', 'r') as file: get_path = file.read() get_path_len = len(get_path) get_path = get_path[:get_path_len - 7] sys.path.append(get_path) # This removes the data widgets when the back button is pressed def delete_data_widgets(): from main_menu_module import main_menu from main_menu_module import key_path from main_menu_module import fernet # Delete the widgets from the data menu data_frame_left.destroy() data_frame_right.destroy() main_menu(key_path, fernet) # This is the command for the listbox in the data menu def data_listbox_show(selected_option): data_textbox.configure(state='normal') data_textbox.delete('1.0', 'end') index_num = names.index(selected_option) data_textbox.insert('end', data_info[index_num]) print(names[index_num]) print(names[index_num].split('.', 1)[1]) data_textbox.configure(state='disabled') # This is the data menu def data_menu(): from main_menu_module import fernet from main import root data = os.listdir('data') data_len = len(data) global names names = [] global data_info data_info = [] for file in data: # Setting up the path to the file if PLATFORM == 'Windows': file_path = 'data\\' + str(file) else: file_path = 'data/' + str(file) # Opening the file with open(file_path, 'rb') as fileR: original = fileR.read() # Decrypting the file decrypted = fernet.decrypt(original) # Filling in the info from the profiles data_info.append(decrypted) # Decrypting the names old_name = bytes(str(file), 'utf-8') new_name = str(fernet.decrypt(old_name)) new_name = new_name[2:] new_name = new_name[:-1] # Filling in the names of the profiles names.append(new_name) global data_frame_left data_frame_left = CTkFrame(master=root, width=100, height=100) global data_back_button data_back_button = CTkButton(master=data_frame_left, text='Back', command=delete_data_widgets) data_back_button.pack(side=TOP, fill=BOTH) global data_listbox data_listbox = CTkListbox(master=data_frame_left, command=data_listbox_show, scrollbar_button_color='#1f6aa5', border_color='#1f6aa5') data_listbox.pack(side=TOP, fill=BOTH, expand=YES) i = 1 for name in names: data_listbox.insert(i, name) i = i + 1 data_frame_left.pack(side=LEFT, fill=BOTH) global data_frame_right data_frame_right = CTkFrame(master=root) global data_textbox data_textbox = CTkTextbox(master=data_frame_right, scrollbar_button_color='#1f6aa5', border_color='#1f6aa5') data_textbox.pack(side=LEFT, fill=BOTH, expand=YES) data_textbox.configure(state='disabled') data_frame_right.pack(side=LEFT, fill=BOTH, expand=YES)
解决方法
要在CTkTextbox中插入解密后的图片,需要结合Pillow处理图片字节,再用Tkinter的image_create方法插入。操作步骤如下:
- 安装依赖库:先安装Pillow用于图片处理
pip install pillow
- 导入必要模块:在代码开头添加以下导入
from PIL import Image, ImageTk import io
- 修改
data_listbox_show函数:替换原函数逻辑,增加图片判断与插入功能
def data_listbox_show(selected_option): data_textbox.configure(state='normal') data_textbox.delete('1.0', 'end') index_num = names.index(selected_option) file_name = names[index_num] decrypted_data = data_info[index_num] # 定义支持的图片格式后缀 image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'] # 判断当前选中文件是否为图片 if any(file_name.lower().endswith(ext) for ext in image_extensions): try: # 将解密后的字节数据转为PIL Image对象 img = Image.open(io.BytesIO(decrypted_data)) # 适配文本框宽度调整图片大小(可选,可根据需求修改) textbox_width = data_textbox.winfo_width() - 20 # 留边距 if img.width > textbox_width: scale_ratio = textbox_width / img.width new_size = (int(img.width * scale_ratio), int(img.height * scale_ratio)) img = img.resize(new_size, Image.Resampling.LANCZOS) # 转为Tkinter可识别的PhotoImage tk_image = ImageTk.PhotoImage(img) # 插入图片到文本框末尾 data_textbox.image_create('end', image=tk_image) # 保存图片引用,防止被Python垃圾回收机制销毁 data_textbox.image_reference = tk_image except Exception as e: # 图片加载失败时显示错误信息 data_textbox.insert('end', f"图片加载失败: {str(e)}") else: # 非图片文件,尝试解码为文本显示 try: text_content = decrypted_data.decode('utf-8') data_textbox.insert('end', text_content) except UnicodeDecodeError: # 无法解码为文本时提示 data_textbox.insert('end', "该文件无法解码为文本数据") data_textbox.configure(state='disabled')
关键注意点
- 保存图片引用:必须将
PhotoImage对象赋值给文本框的属性(如data_textbox.image_reference),否则Python会回收这个对象,导致图片无法显示。 - 图片缩放:根据文本框宽度调整图片大小可以避免图片超出显示区域,也可以根据需求去掉缩放逻辑,让图片保持原始尺寸。
- 格式兼容:代码中列出了常见的图片格式,可根据需要添加更多格式后缀。
内容的提问来源于stack exchange,提问作者dkolev00
相关产品推荐
相关产品推荐

