[Tkinter-discuss] background threading

Michael Lange klappnase at web.de
Wed Apr 7 11:04:21 CEST 2010


Hi,

On Tue, 06 Apr 2010 18:37:42 -0400
Kevin Walzer <kw at codebykevin.com> wrote:

> On 4/6/10 5:03 PM, Nemes Andrei wrote:
> 
> >
> > Another solution to the problem would be pointing me to a more
> > convenient tray icon constructor (instructions how to use would be
> > greatly appreciated) if you know any.
> >
> > I hope someone can help me. Thank you for your time and support.
> 
> This seems a rather convoluted way to do things. There are various Tk 
> extensions that provide system tray functionality and it should be 
> fairly simple to write a Python wrapper for them.
> 
> If you're on Windows, look at winico:
> 
> http://wiki.tcl.tk/4089
> 
> If you're on *Nix, look at tktray:
> 
> http://wiki.tcl.tk/5972
> 
> or freedock:
> 
> http://wiki.tcl.tk/4090
> 
> --Kevin
> 

If you want to use tktray, I already wrote a wrapper for it;
to create a tray icon, you can do something like:

root = Tk()
root.withdraw()
img = PhotoImage(file='image.gif')
icon = TkTray.Icon(root)
icon.configure(image=img)
icon.menu.add_command(label='Quit', command=root.quit)

HTH

Michael

######## file TkTray.py #####################################

import Tkinter

class Icon(Tkinter.BaseWidget, Tkinter.Wm):
    def __init__(self, master=None, cnf={}, **kw):

        if not master:
            if Tkinter._support_default_root:
                if not Tkinter._default_root:
                    Tkinter._default_root = Tkinter.Tk()
                master = Tkinter._default_root
        self.TktrayVersion = master.tk.call('package', 'require', 'tktray')

        # stolen from Tkinter.Toplevel
        if kw:
            cnf = Tkinter._cnfmerge((cnf, kw))
        extra = ()
        for wmkey in ['screen', 'class_', 'class', 'visible', 'colormap']:
            if cnf.has_key(wmkey):
                val = cnf[wmkey]
                # TBD: a hack needed because some keys
                # are not valid as keyword arguments
                if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
                else: opt = '-'+wmkey
                extra = extra + (opt, val)
                del cnf[wmkey]
        Tkinter.BaseWidget.__init__(self, master, 'tktray::icon', cnf, {}, extra)
        self.protocol("WM_DELETE_WINDOW", self.destroy)

        self.menu = Tkinter.Menu(self, tearoff=0)
        self.bind('<3>', self._popupmenu)

    def bbox(self):
        return self._getints(self.tk.call(self._w, 'bbox')) or None

    def _popupmenu(self, event):
        w, h = self.menu.winfo_reqwidth(), self.menu.winfo_reqheight()
        x0, y0, x1, y1 = self.bbox()
        # get the coords for the popup menu; we want it to the mouse pointer's
        # left and above the pointer in case the taskbar is on the bottom of the
        # screen, else below the pointer; add 1 pixel towards the pointer in each
        # dimension, so the pointer is '*inside* the menu when the button is being
        # released, so the menu will not unpost on the initial button-release event
        if y0 > self.winfo_screenheight() / 2:
            # assume the panel is at the bottom of the screen
            x, y = event.x_root - w + 1, event.y_root - h + 1
        else:
            x, y = event.x_root - w + 1, event.y_root - 1
        # make sure that x is not outside the screen
        if x < 5:
            x = 5
        self.menu.tk_popup(x, y)

#################################################################


More information about the Tkinter-discuss mailing list