views:

69

answers:

2

Using wxPython, I created a taskbar icon and menu. Everything works fine (in Windows at least) upon right-click of the icon: i.e., the menu is displayed, and automatically hidden when you click somewhere else, like on Windows' taskbar.

Now I do want to have the menu appear when the icon is left-clicked as well. So I inserted a Bind() to a left-click in the Frame class wrapper, calling the CreatePopupMenu() of the taskbar icon:

import wx
class BibTaskBarIcon(wx.TaskBarIcon):
    def __init__(self, frame):
        wx.TaskBarIcon.__init__(self)
        self.frame = frame
        icon = wx.Icon('test_icon.ico', wx.BITMAP_TYPE_ICO)
        self.SetIcon(icon, "title")

    def CreatePopupMenu(self):
        self.menu = wx.Menu()
        self.menu.Append(wx.NewId(), "dummy menu ")
        self.menu.Append(wx.NewId(), "dummy menu 2")
        return self.menu

class TaskBarFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, style=wx.FRAME_NO_TASKBAR)
        ...
        self.tbicon = BibTaskBarIcon(self)
        wx.EVT_TASKBAR_LEFT_UP(self.tbicon, self.OnTaskBarLeftClick)
        ...

    def OnTaskBarLeftClick(self, evt):
        self.PopupMenu(self.tbicon.CreatePopupMenu())

    ...
def main(argv=None):
    app = wx.App(False)
    TaskBarFrame(None, "testing frame")
    app.MainLoop()

This works fine, except that the menu does not disappear automatically when you click somewhere else on your screen. In fact, left-clicking multiple times on the icon creates multiple menus. The only way to hide the menu(s) is to click on one of its items (which you don't always want). I've looked at the available methods of TaskbarIcon, but I failed to be clear about which one to use to hide the menu (.Destroy() didn't work). Moreover, I don't know which event to bind it to (there is a EVT_SET_FOCUS, but I couldn't find any EVT_LOOSE_FOCUS or similar).

So, how to hide the menu upon losing focus?

EDIT: I've inserted a bit more code, to make it more clear

A: 

I think the problem here is that the PopupMenu is usually used in a program's context, not a little icon in the system tray. What that means is that in a normal frame, the popup menu would detect the click the you clicked off of it. Here, you are clicking outside of the wxPython program. Also, the PopupMenu is usually used with EVT_CONTEXT_MENU, not this taskbar event.

You can try wx.EVT_KILL_FOCUS and see if that works since it should theoretically fire when you click off the menu. Or you could ask on the official wxPython forum here: http://groups.google.com/group/wxpython-users/topics


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Mike Driscoll
A: 

Ah, I've discovered what went wrong. In the statement

self.PopupMenu(self.tbicon.CreatePopupMenu())

I had bound the popup menu to the frame, instead of to the taskbar icon.

By changing it to:

self.tbicon.PopupMenu(self.tbicon.CreatePopupMenu())

all is working well now.

Thanks for all remarks

Rabarberski