如何在Tkinter Label中添加文件系统链接、可选中文本并优化现有代码
问题1解决方案:实现可复制、可点击跳转的路径展示
- 不要用Label组件展示结果,替换为Text组件:原生支持文本选中复制,还可以给指定文本段绑定点击事件
- 给包含"NO TRANSMITTAL"的路径添加自定义tag,绑定左键点击事件,触发时调用系统默认程序打开对应文件夹,跨平台兼容逻辑参考:
import subprocess import sys def open_folder(path): if sys.platform == 'win32': os.startfile(path) elif sys.platform == 'darwin': subprocess.run(['open', path]) else: subprocess.run(['xdg-open', path])
- 在Text中插入路径时给路径段绑定tag和点击事件即可实现点击跳转。
问题2 代码优化建议
- 修复明显bug:现有代码中
substring_drawings_1未定义,直接运行会报错,需要先声明这个变量的匹配规则 - 移除全局变量:
list_of_folders、out_folders等变量放到doStuff函数内部,避免多次点击检查按钮时数据累加出错 - 不要随意修改全局工作目录:删除
os.chdir(o)逻辑,直接用完整路径判断文件即可,避免影响其他功能 - 优化导入方式:不要用
from tkinter import *,改为显式导入,避免命名冲突 - 优化遍历逻辑:不需要先存储全量路径再过滤,直接在
os.walk遍历的时候判断是否是6_Out文件夹,减少不必要的内存占用 - 变量命名规范化:替换
a、E、c这类单字母无意义变量为语义化命名,提升代码可维护性 - 增加滚动条:长结果支持滚动查看,避免内容超出窗口
修改后可运行完整代码
import os import sys import subprocess import tkinter as tk from tkinter import ttk from tkinter import filedialog # 全局配置 SUBSTRING_TRANSMITTAL = "Transmittal" SUBSTRING_DRAWINGS_0 = '.pdf' SUBSTRING_DRAWINGS_1 = 'Dwg' # 原代码未定义,这里按常见场景补充,可自行修改匹配规则 def open_folder(path): """跨平台打开指定文件夹""" if sys.platform == 'win32': os.startfile(path) elif sys.platform == 'darwin': subprocess.run(['open', path], check=False) else: subprocess.run(['xdg-open', path], check=False) def get_folder_path(): folder_selected = filedialog.askdirectory() folder_path_var.set(folder_selected) def do_stuff(): # 清空上次结果 result_text.config(state=tk.NORMAL) result_text.delete(1.0, tk.END) root_folder = folder_path_var.get() if not root_folder: result_text.insert(tk.END, "请先选择要检查的文件夹\n") result_text.config(state=tk.DISABLED) return result_text.insert(tk.END, f"Checking for Transmittal in {root_folder}\n") # 直接遍历过滤6_Out文件夹,不需要存储全量路径 out_folders = [] for path, _, _ in os.walk(root_folder): if '6_Out' in os.path.basename(path): out_folders.append(path) for folder in out_folders: files = os.listdir(folder) has_transmittal = any(SUBSTRING_TRANSMITTAL in f for f in files) has_pdf = any(SUBSTRING_DRAWINGS_0 in f for f in files) has_dwg = any(SUBSTRING_DRAWINGS_1 in f for f in files) relative_path = folder[len(root_folder):] if has_transmittal: result_text.insert(tk.END, f"{relative_path} ---> Transmittal OK\n") else: if has_pdf and has_dwg: # 插入可点击路径 result_text.insert(tk.END, f"{relative_path} ------ ") # 给路径加tag绑定点击事件 path_tag = f"path_{folder}" result_text.insert(tk.END, "NO TRANSMITTAL", (path_tag,)) result_text.tag_bind(path_tag, "<Button-1>", lambda e, p=folder: open_folder(p)) result_text.tag_config(path_tag, foreground="blue", underline=1) result_text.insert(tk.END, " ------\n") for f in files: result_text.insert(tk.END, f" {f}\n") # 禁止编辑,仅允许选中复制 result_text.config(state=tk.DISABLED) # 初始化GUI root = tk.Tk() root.title("MY SCRIPT") folder_path_var = tk.StringVar() # 第一行选择文件夹 label_select = ttk.Label(root, text="选择要检查的文件夹:") label_select.grid(row=0, column=0, padx=5, pady=5, sticky=tk.W) entry_folder = ttk.Entry(root, textvariable=folder_path_var, width=50) entry_folder.grid(row=0, column=1, padx=5, pady=5) btn_browse = ttk.Button(root, text="浏览文件夹", command=get_folder_path) btn_browse.grid(row=0, column=2, padx=5, pady=5) # 第二行操作按钮 btn_check = ttk.Button(root, text="开始检查", command=do_stuff) btn_check.grid(row=1, column=0, padx=5, pady=10) btn_exit = ttk.Button(root, text="退出", command=root.destroy) btn_exit.grid(row=1, column=2, padx=5, pady=10) # 结果展示区域(带滚动条) result_frame = ttk.Frame(root) result_frame.grid(row=2, column=0, columnspan=3, padx=5, pady=5, sticky=tk.NSEW) scrollbar = ttk.Scrollbar(result_frame) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) result_text = tk.Text(result_frame, wrap=tk.WORD, yscrollcommand=scrollbar.set, borderwidth=3, justify=tk.LEFT) result_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.config(command=result_text.yview) result_text.config(state=tk.DISABLED) # 自适应窗口大小 root.grid_rowconfigure(2, weight=1) root.grid_columnconfigure(1, weight=1) root.mainloop()
使用说明:蓝色带下划线的NO TRANSMITTAL字样点击即可跳转到对应文件夹,所有文本支持选中后Ctrl+C复制
内容的提问来源于stack exchange,提问作者Saverio Vasapollo
相关产品推荐
相关产品推荐

