I found the hackicon project in SourceForge but was dismayed to see
that it required an extension DLL. Looking at the source, it seemed
easy enough to implement in pure Python as long as win32all was
installed.
Here's my solution:
----
import atexit
from Tkinter import *
import win32con
import win32gui
def set_icon(window, icon_path):
if not win32gui.IsWindowVisible(int(window.winfo_id())):
window.wait_visibility(window)
hwnd = win32gui.GetParent(int(window.winfo_id()))
icon = win32gui.LoadImage(0, icon_path, win32con.IMAGE_ICON, 0, 0,
win32con.LR_DEFAULTSIZE |
win32con.LR_LOADFROMFILE)
win32gui.SendMessage(hwnd, win32con.WM_SETICON,
win32con.ICON_BIG, icon)
win32gui.SendMessage(hwnd, win32con.WM_SETICON,
win32con.ICON_SMALL, icon)
atexit.register(destroy_icon, icon)
def destroy_icon(icon):
win32gui.DestroyIcon(icon)
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
set_icon(root, "C:\\Python23\\py.ico")
root.mainloop()
----
My question is in regards to the wait_visibility method. The call to
GetParent fails unless I do this. Why is that? Also, if I call
set_icon a second time, wait_visibility doesn't return until after the
root's mainloop ends at which point the window's been deleted causing
the program to crash. Hence, my call to IsWindowVisible. Is there a
Tkinter method to check a window's visibility?
I guess I don't understand what wait_visibility does that makes it
only work once. Lundh's "An Introduction to Tkinter" says that it
enters a local event loop but that other parts of the application will
still work as usual. Does that mean it responds to events on its own
thread?
Thanks,
Jason