Python Treeview:替换显示文件名并保留双击复制文件功能
优化方案:Treeview显示真实文件名,双击仍复制原文件
要实现需求,核心是建立匿名ID与真实名称的映射字典,并让Treeview条目关联原文件的绝对路径,这样既可以显示真实名称,双击操作也能直接获取原文件路径完成复制。
关键修改点
- 加载名称映射:读取存储映射关系的TXT文件,生成ID到真实名称的字典。
- Treeview条目绑定原路径:遍历文件时,给每个条目存储原文件的绝对路径,避免通过显示名称拼接路径的错误。
- 替换显示名称:判断文件是否为照片(根据后缀),若在映射字典中存在对应关系,就显示真实名称,否则保留原名称。
- 简化剪贴板复制逻辑:直接从条目属性中获取原绝对路径,无需递归拼接路径。
修改后的完整代码
import os import subprocess import tkinter as tk import tkinter.ttk as ttk class App(tk.Frame): def __init__(self, master, path): tk.Frame.__init__(self, master) self.tree = ttk.Treeview(self, show='tree') ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview) xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview) self.tree.configure(yscroll=ysb.set, xscroll=xsb.set) self.tree.heading('#0', text=path, anchor='w') self.abspath = os.path.abspath(path) # 加载名称映射字典,假设映射文件在目标文件夹下名为mapping.txt self.name_mapping = self.load_name_mapping() self.tree.bind("<Double-Button-1>", self.copy_to_clipboard) self.tree.grid(row=0, column=0) ysb.grid(row=0, column=1, sticky='ns') xsb.grid(row=1, column=0, sticky='ew') self.grid() self.reload() def load_name_mapping(self): """加载ID与真实名称的映射字典,假设TXT每行格式为:匿名ID 真实名称""" mapping_dict = {} mapping_file = os.path.join(self.abspath, "mapping.txt") if os.path.exists(mapping_file): with open(mapping_file, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if not line: continue # 分割ID和真实名称,若用其他分隔符可替换为split(':')等 parts = line.split(maxsplit=1) if len(parts) == 2: anon_id, real_name = parts mapping_dict[anon_id] = real_name return mapping_dict def copy_to_clipboard(self, event, *args): item = self.tree.focus() # 直接从条目的values中获取原文件的绝对路径 absolute_path = self.tree.item(item, 'values')[0] if absolute_path and os.path.exists(absolute_path): # Windows下复制文件到剪贴板的powershell命令 cmd = r"Get-Item '{}' | Set-Clipboard -Path".format(absolute_path) subprocess.run(["powershell", "-command", cmd], shell=True) print(f"已复制:{absolute_path}") def reload(self): self.tree.delete(*self.tree.get_children()) root = self.tree.insert('', 'end', text=self.abspath, open=True, values=(self.abspath,)) self.process_directory(root, self.abspath) def process_directory(self, parent, path): try: for p in os.listdir(path): abspath = os.path.join(path, p) isdir = os.path.isdir(abspath) # 判断是否为照片文件,可根据实际后缀扩展 photo_extensions = ('.jpg', '.jpeg', '.png', '.gif', '.bmp') display_name = p # 如果是照片文件,且在映射字典中存在对应ID if not isdir and p.lower().endswith(photo_extensions): # 去掉后缀获取匿名ID anon_id = os.path.splitext(p)[0] if anon_id in self.name_mapping: display_name = self.name_mapping[anon_id] # 插入条目时,将原绝对路径存入values属性 oid = self.tree.insert(parent, 'end', text=display_name, values=(abspath,), open=False) if isdir: self.process_directory(oid, abspath) except PermissionError: pass root = tk.Tk() path_to_my_project = r'Path\to\project' app = App(root, path=path_to_my_project) app.mainloop()
代码说明
load_name_mapping方法:读取mapping.txt生成映射字典,若你的TXT用其他分隔符(如冒号),修改split参数即可适配。process_directory方法:遍历文件时识别照片文件,替换显示名称,同时将原文件绝对路径存入Treeview条目的values属性,这是保证双击复制原文件的核心。copy_to_clipboard方法:直接从条目属性中提取原路径,调用powershell命令完成复制,逻辑更简洁可靠。
内容的提问来源于stack exchange,提问作者Puje
相关产品推荐
相关产品推荐

