[Tkinter] LONG POST ALERT: Setting application icon on Linux

Tim Jarman tmj at SPAMLESSjarmania.com
Sun Mar 27 07:27:25 EST 2005


Apologies in advance for the long post - I wanted to be sure I included all
the relevant details. The answer is probably very, very simple.

I am doing something stupid here, but I don't know what it is. I'm writing
an application with a Tkinter GUI (Python 2.4, Tcl/Tk 8.4.) and I want to
put a custom icon on the main window. 

I've followed (so far as I understand it) the recipe in the eff-bot's
splendid Introduction to Tkinter - see:
http://www.pythonware.com/library/tkinter/introduction/x9905-icon-methods.htm
- but it isn't working for me. Clearly there#s something I didn't get.

I need a solution for Linux initially (Mandrake 10.1/KDE 3.2 if it makes a
difference) and maybe OS/X in the future. The only solutions I've founds on
Google are Windows-specific.

Here's what I have at the moment, reduced to its essentials:

<code>
# Display an application icon.

import os.path
import Tkinter as tk

APP_NAME = "Icon Test"
HOME = "/home/tim/Projects/tkDev/playwright"


def main():
    "Main entry point for the application."
    # Create the root window.
    root = tk.Tk()
    root.title(APP_NAME)
    
    # Set the icon.
    print "current icon name = ", root.iconname()
    icon_path = os.path.join(HOME, "icon.gif")
    print "icon_path =",  icon_path
    try:
        icon_image = tk.PhotoImage(file=icon_path)
        print "icon_image =", icon_image
        icon_label = tk.Label(image=icon_image)
        print "icon_label =",  icon_label
        assert icon_label.master is root
        print "about to fail.."
        root.iconwindow(icon_label)
        print "success??!"
    except IOError:
        pass

    # Create and show the main window.
    root.mainloop()


# Bootstrap code.
if __name__ == "__main__":
    main()
</code>

And here's the output I get when I run it:

<output>
current icon name =
icon_path = /home/tim/Projects/tkDev/playwright/icon.gif
icon_image = pyimage1
icon_label = .1076669484
about to fail..
Traceback (most recent call last):
  File "test_icon.py", line 38, in ?
    main()
  File "test_icon.py", line 27, in main
    root.iconwindow(icon_label)
  File "/usr/local/lib/python2.4/lib-tk/Tkinter.py", line 1473, in
wm_iconwindow
    return self.tk.call('wm', 'iconwindow', self._w, pathName)
_tkinter.TclError: can't use .1076669484 as icon window: not at top level
</output>

Obviously the root window doesn't even get displayed.

I don't understand the error message. How can I make the Label "top level"
enough to do the job? It's a child of root. Calling .pack() doesn't seem to
help (although if I comment out the iconwindow() call so that the window
actually appears, I can see that the GIF file has loaded correctly).

Do I need to hide the root window and create a new Toplevel for my app's
main window? I thought root would be an instance of Toplevel. As you can
tell, I'm a bit confused here!

Wishing-I-was-doing-this-in-wxPython-ly,

Tim J

-- 
Website: www DOT jarmania FULLSTOP com



More information about the Python-list mailing list