Python动态创建带图标的.lnk按钮仅最后一个生效问题求助
问题描述
- 目标:编写脚本读取运行目录下的
.lnk文件,为每个文件创建带对应exe图标的按钮,点击按钮可启动该快捷方式,实现Windows任务栏快捷弹出菜单。 - 问题:不为
tk.Button设置image参数时所有按钮正常工作,一旦添加图标,仅最后创建的按钮能触发点击事件,前几个按钮点击无响应。 - 现象:前两个按钮点击无任何反应,第三个按钮正常工作;注释掉添加图标的代码后,所有按钮均可正常打开对应的快捷方式。
代码实现
import tkinter as tk import os import pyautogui from win32api import GetSystemMetrics from PIL import Image, ImageTk import win32com.client import win32gui import win32ui def execlink(linkpath): os.startfile(linkpath) class IconExtractor: def __init__(self): self.photo = None self.root = None self.label = None def extract_icon(self, exe_path, ico_path): icon_handles, num_icons = win32gui.ExtractIconEx(exe_path, 0) if icon_handles: h_icon = icon_handles[0] hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, 32, 32) hdc = hdc.CreateCompatibleDC() hdc.SelectObject(hbmp) hdc.DrawIcon((0, 0), h_icon) hbmp.SaveBitmapFile(hdc, ico_path) win32gui.DestroyIcon(h_icon) else: print("No icons found in the executable.") def on_closing(self): self.root.destroy() def main(self, lnk_path, ico_path): shell = win32com.client.Dispatch("WScript.Shell") shortcut = shell.CreateShortCut(lnk_path) target_path = shortcut.TargetPath if os.path.exists(target_path): self.extract_icon(target_path, ico_path) if os.path.exists(ico_path): with Image.open(ico_path) as img: img = img.convert("RGBA") self.photo = ImageTk.PhotoImage(img) else: print("Failed to retrieve the target path.") class LinksMenu: def __init__(self): self.MainWindow = tk.Tk() self.MainWindow.geometry("100x40+" + str(pyautogui.position()[0]) + "+100") self.MainWindow.overrideredirect(True) self.MainWindow.bind("<KeyPress>", self.closing) self.btnframe = tk.Frame(self.MainWindow) self.btnframe.configure(bg='') self.btnframe.columnconfigure(0, weight=1) count = 1 files = [File for File in os.listdir('.') if os.path.isfile(File)] for File in files: if File[-4:] == ".lnk": GetImage.main(os.path.realpath(File), os.path.dirname(os.path.realpath(File)) + '\\' + File[0:-4] + '.ico') newbutton = tk.Button( self.btnframe, name=File[0:-4].lower() + 'btn', text=File[0:-4], compound=tk.LEFT, image=GetImage.photo, font=('Arial', 14), bg='DodgerBlue4', command=lambda m=os.path.realpath(File): [execlink(m), self.close_after_choice()] ) newbutton.grid( padx=2, pady=2, row=count, column=0, sticky=tk.W+tk.E ) count += 1 self.btnframe.pack(fill='x') self.MainWindow.geometry( "300x" + str(count*45) + "+" + str(pyautogui.position()[0]) + "+" + str(GetSystemMetrics(1)-(count*45)) ) self.MainWindow.configure(bg='') self.MainWindow.mainloop() def closing(self, event): if event.state == 8 and event.keysym == "Escape": self.MainWindow.destroy() def close_after_choice(self): self.MainWindow.destroy() if __name__ == "__main__": GetImage = IconExtractor() LinksMenu()
已尝试的解决方法
- 将图标保存为png后通过文件路径读取
- 将图片存入新对象再添加到
tk.Button - 在内存中将图标转为png后添加到按钮
- 不动态创建按钮(排除重复使用对象名的问题)
- 销毁用于获取图片的对象
注:图标提取代码由ChatGPT辅助生成。
内容的提问来源于stack exchange,提问作者TempusFugit
相关产品推荐
相关产品推荐

