April 22, 2005
Windows system tray icons with Python

Two or three years ago, I put together a little Python app that provided shortcuts to useful places in our gruesome internal timesheet system. (The URLs aren't static, so I needed a script.) I used PyWin32 to enable you to launch these from the Windows systems tray, based on demo code by Mark Hammond. My script was a bit of a bodge, though; the UI code and the logic code were all mixed up. I always intended to go back and separate everything out, but I never got around to it...

Until now. I had a couple of changes that needed making, so I grasped the nettle and put together a general purpose module; SysTrayIcon.py. It still needs documentation, but you can see basically how to use it from the demo code at the bottom.

There is one problem with it, though - on XP, if you set up a menu item with an icon, the menu item text overlaps the icon image by a few pixels, and I can't work out how to fix it. Any pointers?

Oh, and yes, yes, I know it's not called the system tray really. But that's what everyone calls it anyway.

Posted to Python by Simon Brunning at April 22, 2005 01:16 PM
Comments

Thanks a bunch. I can find this rather useful.

Posted by: RunLevelZero on April 22, 2005 05:03 PM

Thanks for this nice script.

I had to sligthly modify it to make it working on Python 2.3

I add the line:
from sets import Set

and modify the line:
self.menu_actions_by_id = set()
into:
self.menu_actions_by_id = Set()

So if someone have the same problem it could solve it slightly faster I suppose.

Thanks again.

Vivian De Smedt.

Posted by: Vivian De Smedt on April 22, 2005 06:11 PM

win32gui in python seems quite useful. I didn't know python could be so tightly integrated with Windows.

Posted by: Stephen on April 22, 2005 07:11 PM

Simon, thanks a bunch for posting this! You've wrapped it up nicely and it makes it look simple, but I'm sure it would have taken me days or hours to dig through the docs to figure this out.

Posted by: Brian Dorsey on April 23, 2005 12:38 AM

Another way to do it would be to use Jython + Java Desktop Integration Components (JDIC)

Posted by: Jonathan Aquino on April 23, 2005 02:32 AM

The pixel overlap looks to be the way XP's systray displays things. I notice that every other text popup on the system tray does the same thing.

Posted by: Mark Hertel on April 23, 2005 05:38 PM

In reply to Vivian De Smedt's comment, I have this alternate suggestion.

try:
set
except:
try:
from sets import Set
except ImportError, why:
print 'Error. `set\' was not defined, and we could not import the sets module as required.'
print 'Error returned was: '+str(why)
#assuming that sys was imported
sys.exit((-1,'`Set` was unavailable, so we cannot continue'))
else:
set = Set

Hopefully that would be a widely compatible method of resolving the `set` function.

-Wes

Posted by: Wes on April 27, 2005 11:33 PM

Very nice :-)

Posted by: Mustafa Görmezer on July 27, 2005 09:40 AM

Hi Simon,

Thanx to your good work, I didn't have to reinvent the wheel here.

I've also wrapped this up into a more General Application Framework I call pysystray-win32 at http://datavibe.net/~essiene/pysystray

This has save me a lot of time too, than using SysTrayIcon in the raw.

Do you have any particular licensing requirements? As i've released this on sourceforge. If you want to reach me, i'm at essiene _at_ datavibe _dot_ net

Posted by: Essien Ita Essien on August 22, 2005 12:20 PM

Hmmm. I've emailed you at that address a couple of times, Essien, but clearly you aren't getting my mails. I wonder what's up?

Any road up, help yourself. Consider SysTrayIcon.py to be under an "Aleister Crowley" style license - "Do what thou wilt shall be the only law".

Err, but don't sue me if it doesn't work. ;-)

Posted by: Simon Brunning on August 22, 2005 01:10 PM

I really wonder what's up with the funky email anyways, it works mostly, maybe a grumpy Elephant is sitting infront of the SMTP server :)

> Any road up, help yourself. Consider
> SysTrayIcon.py to be under an "Aleister Crowley"
> style license - "Do what thou wilt shall be the
> only law".

Wheee!!! :)

> Err, but don't sue me if it doesn't work. ;-)
lol

Posted by: Essien Ita Essien on August 23, 2005 10:39 AM

This is quite buggy. When I minimize my window, the window is then hidden with window.withdraw(). It then unhides the icon like it should, but when I double click on the icon, to trigger a window.deiconify(), the whole program locks up and I get no traceback. Any ideas?

Posted by: Andrew on November 14, 2005 10:44 PM

Hi Simon,

Nice little script, and well done Essian for doing a nice little wrapper & installer.

It looks as if the icons could be shifted to the left another 10-15 pixels as there's a gap on the left side of the menu. So in other words the icons are currently appearing with the text label, and not in the designated icon location..

Looking at the menus of my other system tray icons, their icons are 1-2px from the left border. Maybe there's another way to specify how to load an icon into the menu via the win32 library?

I'll have a tinker and see if I can figure it out, though if anybody else has achieved it, please post it up :)

Posted by: Joe on March 10, 2007 12:10 AM
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?