Изображение в Treview

#python #image #tkinter #treeview

Вопрос:

пожалуйста, изображение в дереве.вставка отображается только для последнего элемента вставки в моем представлении дерева, но я хотел бы, чтобы оно отображалось везде

Это мой код

 def openFichiersDossiers(h):  global img_file  global chemin  racine = tree1.selection()  b = (tree1.item(racine)['values'])[3]  chemin_absolu = Path(b)  if chemin_absolu.is_dir():  for x in tree1.get_children():  tree1.delete(x)  try:  for entry in os.listdir(chemin_absolu):  try:  path1 = Path(b   "\"   entry)  if path1.is_dir():  try:  tree1.insert(parent='', index=0, text=entry,  values=[time.ctime(os.path.getmtime(path1)), "   Dossier",'', path1], image=img_dir)  except OSError as e:  showerror("Erreur", message=str(e))  else:  try:  img_file = function.icon(path1)  tree1.insert(parent='', index='end', text=entry,  values=[time.ctime(os.path.getmtime(path1)), "Fichier",  str(os.path.getsize(path1))   ' Byte(s)',   path1],image=img_file)  except OSError as e:  showerror("Erreur", message=str(e))  except OSError as e:  showerror("Erreur", message=str(e))  except OSError as e:  showerror("Erreur", message=str(e))  chemin.append(chemin_acces.cget("text"))  

и это функция, которую я использую для получения изображения

 def icon(p):  if (os.path.splitext(p))[1] == ".docx":  img = PhotoImage(file='images/file_type_word_icon_130070.png')  return img  if (os.path.splitext(p))[1] == ".pdf":  img = PhotoImage(file='images/file-expand_Pdf_icon-icons.com_68956.png')  return img  if (os.path.splitext(p))[1] == ".mp4" or (os.path.splitext(p))[1] == ".mkv":  img = PhotoImage(file='images/videos_myvideos_play_2144.png')  return img  if (os.path.splitext(p))[1] == ".xlsx":  img = PhotoImage(file='images/1486565571-microsoft-office-excel_81549.png')  return img  if (os.path.splitext(p))[1] == ".png" or (os.path.splitext(p))[1] == ".jpeg" or (os.path.splitext(p))[1] == ".gif"   or (os.path.splitext(p))[1] == ".ico" or (os.path.splitext(p))[1] == ".jpg":  img = PhotoImage(file='images/picture_photo_image_icon_131252.png')  return img  if (os.path.splitext(p))[1] == ".txt":  img = PhotoImage(file='images/txt_text_file_format_extension_icon_124600.png')  return img  if (os.path.splitext(p))[1] == ".mp3" or (os.path.splitext(p))[1] == ".m4a":  img = PhotoImage(file='images/apple_music_android_logo_icon_134021.png')  return img  if (os.path.splitext(p))[1] == ".iso":  img = PhotoImage(file='images/iso_20225.png')  return img  if (os.path.splitext(p))[1] == ".rar" or (os.path.splitext(p))[1] == ".zip" or (os.path.splitext(p))[1] == ".7z":  img = PhotoImage(file='images/winrar_14662.png')  return img  if (os.path.splitext(p))[1] == ".exe":  img = PhotoImage(file='images/exe_115515.png')  return img  if (os.path.splitext(p))[1] == ".ppt":  img = PhotoImage(file='images/microsoft_powerpoint_macos_bigsur_icon_189966.png')  return img  if (os.path.splitext(p))[1] == ".pub":  img = PhotoImage(file='images/Publisher_2013_23475.png')  return img  else:  img = PhotoImage(file='images/1492616984-7-docs-document-file-data-google-suits_83406.png')  return img  

Комментарии:

1. сначала отредактируйте вопрос и используйте специальные кнопки для форматирования кода.

2. если у вас много изображений, сохраните их в списке — не назначайте все изображения одной и той же переменной img_file . PhotoImage имеет bug , который удаляет изображение из памяти, когда оно не назначено глобальной переменной или объекту класса. И если вы назначите второе изображение той же глобальной переменной, то bug удалите предыдущее изображение из памяти, и вы не сможете увидеть это изображение. Поэтому создайте список img_file = [] и используйте img_file.append( ...)

3. Я попробовал твой метод, но он делает то же самое

4. Пожалуйста, не могли бы вы написать кусочек кода и отправить мне

5. внешняя функция: all_images = [] , внутренняя функция: img_file = function.icon(path1) , all_images.append(img_file)

Ответ №1:

Если у вас много изображений, сохраните их в списке — не назначайте все изображения одной и той же переменной img_file .

PhotoImage имеет bug , который удаляет изображение из памяти, когда оно не назначено global переменной или объекту класса. И если вы назначите второе изображение той же global переменной, то bug предыдущее изображение будет удалено из памяти, и вы не сможете увидеть это изображение.

Поэтому создайте список all_img_file = [] вне функции и используйте all_img_file.append(img_file)

 all_img_file = []  def openFichiersDossiers(h):   # ... code ...   all_img_file.append(img_file)  

В конце концов, вы также могли бы сделать это в icon


Минимальный рабочий код, который использует этот метод в функции get_icon()

Я добавил другие интересные изменения. Я использую словарь, {extension: image_file_name, ...} чтобы использовать более короткий код. Я также сохраняю специальные значки с именем , например OTHER , DIR вместо расширения.

Я одно место, которое вы используете Path(b) , но позже вы используете os , чтобы получить время, размер, текст, но вы можете использовать функцию внутри Path . Вы можете увидеть это в этой версии.

 from pathlib import Path import time import tkinter as tk import tkinter.ttk as ttk from tkinter.messagebox import showerror  # --- functions ---  def open_files_folderse(path='.'): # PEP8: `lower_case_names`, `English names`    base_folder = Path(path)    if base_folder.is_dir():  for child in tree.get_children():  tree.delete(child)    for full_path in sorted(base_folder.iterdir(), key=lambda x:str.lower(x.name), reverse=True):  try:  stat = full_path.stat()  time_str = time.ctime(stat.st_mtime)  text = full_path.name   if full_path.is_dir():  img_file = get_icon("DIR")  index = '0'  size_str = ''  type_str = "Folder"  else:  img_file = get_icon(full_path)  index = 'end'  size_str = f'{stat.st_size} Byte(s)'  type_str = "File"    values = [time_str, type_str, size_str, full_path]   tree.insert(parent='', index=index, text=text, values=values, image=img_file)  except OSError as e:  showerror("Error", message=str(e))  icon_data = {  ".docx": 'images/file_type_word_icon_130070.png',  ".pdf": 'images/file-expand_Pdf_icon-icons.com_68956.png',    ".mp4": 'images/videos_myvideos_play_2144.png',  ".mkv": 'images/videos_myvideos_play_2144.png',    ".xlsx": 'images/1486565571-microsoft-office-excel_81549.png',    ".png": 'images/picture_photo_image_icon_131252.png',  ".jpeg": 'images/picture_photo_image_icon_131252.png',  ".gif": 'images/picture_photo_image_icon_131252.png',  ".ico": 'images/picture_photo_image_icon_131252.png',  ".jpg": 'images/picture_photo_image_icon_131252.png',    ".txt": 'images/txt_text_file_format_extension_icon_124600.png',    ".mp3": 'images/apple_music_android_logo_icon_134021.png',  ".m4a": 'images/apple_music_android_logo_icon_134021.png',     ".iso": 'images/iso_20225.png',    ".rar": 'images/winrar_14662.png',  ".zip": 'images/winrar_14662.png',  ".7z": 'images/winrar_14662.png',    ".exe": 'images/exe_115515.png',  ".ppt": 'images/microsoft_powerpoint_macos_bigsur_icon_189966.png',  ".pub": 'images/Publisher_2013_23475.png',    # special names    #"OTHER": 'images/1492616984-7-docs-document-file-data-google-suits_83406.png',  "OTHER": 'test/face.png',  "DIR": 'test/face.png', }  #all_icons = [] # list all_icons = {} # dict  def get_icon(path):    if isinstance(path, Path):  ext = path.suffix.lower()  else: # ie. "DIR", "OTHER"  ext = path    # default icon if exension doesn't exists in `icon_data`   if ext not in icon_data:  ext = "OTHER"    #ext = "OTHER" # for test uses the same icon for all files   # list  #icon = tk.PhotoImage(file=icon_data[ext])  #all_icons.append(icon)    # dict  if ext not in all_icons:  try:  all_icons[ext] = tk.PhotoImage(file=icon_data[ext])  except Exception as ex:  print("Exception:", ex)  all_icons[ext] = tk.PhotoImage(file=icon_data["OTHER"])    print('ext:', ext)  icon = all_icons[ext]    return icon  # --- main ---  root = tk.Tk()  tree = ttk.Treeview(root) tree.pack(side='left', fill='both', expand=True)  scroll = tk.Scrollbar(root, command=tree.yview) scroll.pack(side='right', fill='y')  scroll['command'] = tree.yview tree['yscrollcommand'] = scroll.set  open_files_folderse('test')  root.mainloop()   

лицо.png

введите описание изображения здесь

Комментарии:

1. Спасибо, я попробую это