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

T

Tim Jarman

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
 
J

Jeff Epler

Here is a short program that sets Tk's window icon on Linux. My window
manager is icewm, and it uses a scaled version of the "flagup" image
both at the upper-left corner of the window and on the task bar entry
for the window.

import Tkinter
app = Tkinter.Tk()
app.iconbitmap("@/usr/X11R6/include/X11/bitmaps/flagup")
app.mainloop()

As often happens, the Tkinter documentation doesn't tell the whole
story---you have to dig into the Tk documentation. I started with "man
n wm", and read the following:
If bitmap is specified, then it names a bitmap in the standard
forms accepted by Tk (see the Tk_GetBitmap manual entry for
details).
OK, on to Tk_GetBitmap...
@fileName FileName must be the name of a file containing a
bitmap description in the standard X11 or X10 format.
and I happened to know that some bitmaps in this format exist in the
directory I mentioned above. Note that the "standard X11 format" is
monochrome, so you will not be able to use color images with
"iconbitmap" on Linux. Tk doesn't support _NET_WM_ICON for setting
full-color icons.

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFCRt2dJd01MZaTXX0RAj17AJ4k30Z3X87YeBY+J59GvRRNZ01bdACdFJPA
IogJMISWv4+m8dySTalR15g=
=bQtD
-----END PGP SIGNATURE-----
 
T

Tim Jarman

Jeff said:
Here is a short program that sets Tk's window icon on Linux. My window
manager is icewm, and it uses a scaled version of the "flagup" image
both at the upper-left corner of the window and on the task bar entry
for the window.

import Tkinter
app = Tkinter.Tk()
app.iconbitmap("@/usr/X11R6/include/X11/bitmaps/flagup")
app.mainloop()

As often happens, the Tkinter documentation doesn't tell the whole
story---you have to dig into the Tk documentation. I started with "man
n wm", and read the following:
If bitmap is specified, then it names a bitmap in the standard
forms accepted by Tk (see the Tk_GetBitmap manual entry for
details).
OK, on to Tk_GetBitmap...
@fileName FileName must be the name of a file containing a
bitmap description in the standard X11 or X10 format.
and I happened to know that some bitmaps in this format exist in the
directory I mentioned above. Note that the "standard X11 format" is
monochrome, so you will not be able to use color images with
"iconbitmap" on Linux. Tk doesn't support _NET_WM_ICON for setting
full-color icons.

Jeff

Thanks for this, Jeff - I'll do some digging in the Tk docs. My problem is
that I'm trying to use iconwindow() to use a colour image, as opposed to
iconbitmap(), although if push comes to shove I suppose I could use that.

Thanks again for the quick response - on Easter weekend too!

Tim J
 
J

Jeff Epler

I have written a rather hackish extension to use NET_WM_ICON to set
full-color icons in Tkinter apps. You can read about it here:
http://craie.unpy.net/aether/index.cgi/software/01112237744
you'll probably need to take a look at the EWMH spec, too. If KDE
supports NET_WM_ICON, this may work for you (but you'll have to convert
your image manually to the format required for NET_WM_ICON)

Best of luck! Unfortunately, the code is not supported.

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFCS2kUJd01MZaTXX0RAoEiAJsEYXT4aNXwfmWhcS0lFNHXj3+q7QCfSK8z
jJDV5/uLWoCY5tggDUtV17A=
=5yBr
-----END PGP SIGNATURE-----
 
T

Tim Jarman

Jeff said:
I have written a rather hackish extension to use NET_WM_ICON to set
full-color icons in Tkinter apps. You can read about it here:
http://craie.unpy.net/aether/index.cgi/software/01112237744
you'll probably need to take a look at the EWMH spec, too. If KDE
supports NET_WM_ICON, this may work for you (but you'll have to convert
your image manually to the format required for NET_WM_ICON)

Best of luck! Unfortunately, the code is not supported.

Jeff

Thanks very much for the link! I'll take a look.

Tim J
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top