将文件类对象用于 Tk().iconbitmap()

1 投票
2 回答
1206 浏览
提问于 2025-04-16 07:15

我正在用Tkinter写一个程序,最后想用py2exe把它打包成一个exe文件。我想给这个程序加一个图标,这个图标和我打包的exe文件的图标是一样的。请问有没有办法在Tkinter中加入这个图标?比如说通过找到exe文件或者使用类似文件的对象。我知道win32api可以找到当前正在运行的exe文件,但我觉得py2exe会把原始文件提取到临时文件夹,然后再运行,所以可能找不到原来的exe文件。我还想过把图标放在一个包含的文件夹里,但我不确定当前工作目录(cwd)是否会正确设置。谢谢大家的帮助!

2 个回答

2

你可以通过 icon_resources 这个选项把图标嵌入到 py2exe 生成的程序里。

setup(windows=[
    {'script':'toto.py', "icon_resources": [(1, "toto.ico")]},
    ],

然后你可以用 Windows 的 API 来获取这个图标。

import win32gui, win32api, win32con
from ctypes import c_int, windll

hicon = win32gui.CreateIconFromResource(win32api.LoadResource(None, win32con.RT_ICON, 13), True)

只要你知道窗口的 HWND,就可以把图标附加到窗口上。

windll.user32.SendMessageA(c_int(hwnd), c_int(win32con.WM_SETICON), c_int(win32con.ICON_SMALL), c_int(hicon))

LoadResource 中使用的 13 常量是通过像 ResourceHacker 这样的工具获取的。在 ResourceHacker 中,这个常量对应的是图标的文件夹名称。我不太清楚 py2exe 是怎么计算这个值的,也不知道有没有办法强制设置这个值。

我也不确定是否有纯粹的 TkInter 方法可以做到这一点,以及图标是否可以直接在 tkinter 窗口中使用。

希望这些信息对你有帮助。

3

Tk的图像有一个叫做-data的选项,可以让你把图像直接嵌入到代码里。你只需要把图像转换成base64格式。我觉得这个图像最开始得是GIF格式的。

下面是一个可以运行的例子:

import Tkinter as tk
root = tk.Tk()
data = '''R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9P
          T6Ai8P8A/////////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYY
          fh8GIEvpoUZcmtOKAO5rLMva0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYw
          YtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eTYhJDQ3woDGl7foNiKBV7aYeEkHEi
          gnKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOsNYa2q7mcirC5I5Fo
          fsK6hcHHgsSgx4a9yzXK0rrV19gRADs=
       '''
img = tk.PhotoImage(data=data)
label = tk.Label(image=img)
label.pack()
root.mainloop()

撰写回答