【问题标题】:Image in Treview树视图中的图像
【发布时间】:2021-12-31 01:56:37
【问题描述】:

请仅在树视图中的最后一个插入项显示 tree.insert 中的图像,但我希望在任何地方都显示

这是我的代码

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

【问题讨论】:

  • 首先编辑问题并使用特殊按钮格式化代码。
  • 如果您有很多图像,请将它们保留在列表中 - 不要将所有图像分配给同一个变量 img_filePhotoImage 具有bug,当图像未分配给全局变量或类对象时,它会从内存中删除图像。如果你将第二张图片分配给同一个全局变量,那么bug 从内存中删除前一张图片,你就看不到这张图片了。所以创建列表img_file = [] 并使用img_file.append( ...)
  • 我试过你的方法,但效果一样
  • 请你写一段代码并发给我
  • 外部函数:all_images = [],内部函数:img_file = function.icon(path1)all_images.append(img_file)

标签: python image tkinter treeview


【解决方案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, ...},所以我可以使用更短的代码。我还保留了名称为OTHERDIR 之类的特殊图标,而不是扩展名。

我在一个地方使用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()   

face.png

【讨论】:

  • 谢谢我试试这个
猜你喜欢
  • 1970-01-01
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多