Search code examples
python-3.xwxpythonsystem-tray

Python 3 Wx Change tray icon


I'm using WxPython (phoenix new version) to have an icon on the tray bar while the programs runs, but I would some events to change the icon used.

I found this great example to get things started: Quick and easy: trayicon with python?

But it doesn't have the example to cycle through icons.

Just after the imports it has this line:

TRAY_ICON = 'icon.png'

And I've tried to use that as sort of a variable, and adding the following line to an event (it has some mock events like hellow world on a right click

TRAY_ICON = 'icon2.png'

but it didn't work =//

I only found examples in c, and one in python but using a very complex win32 alternative that I can't figure out


Solution

  • This should provide you with enough to solve your problem.

    import wx
    import wx.adv
    
    ICON = 'toggle1.png'
    ICONS = ["toggle1.png", "toggle2.png"]
    
    X=[1,0]
    
    class TaskBarIcon(wx.adv.TaskBarIcon):
        def __init__(self, frame):
            self.frame = frame
            self.toggle = 0
            wx.adv.TaskBarIcon.__init__(self)
            self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.OnToggle)
            self.OnSetIcon(ICON)
    
        def CreatePopupMenu(self):
            menu = wx.Menu()
            togglem = wx.MenuItem(menu, wx.NewId(), 'Toggle Icon')
            menu.Bind(wx.EVT_MENU, self.OnToggle, id=togglem.GetId())
            menu.Append(togglem)
            menu.AppendSeparator()
            flashm = wx.MenuItem(menu, wx.NewId(), 'Flash Icon')
            menu.Bind(wx.EVT_MENU, self.OnTimer, id=flashm.GetId())
            menu.Append(flashm)
            menu.AppendSeparator()
            quitm = wx.MenuItem(menu, wx.NewId(), 'Quit')
            menu.Bind(wx.EVT_MENU, self.OnQuit, id=quitm.GetId())
            menu.Append(quitm)
            return menu
    
        def OnSetIcon(self, path):
            icon = wx.Icon(path)
            self.SetIcon(icon, path)
    
        def OnToggle(self, event):
            self.toggle=X[self.toggle]
            use_icon = ICONS[self.toggle]
            self.OnSetIcon(use_icon)
    
        def OnTimer(self,event):
            self.timer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.OnInUseTimer)
            self.timer.Start(1000)
    
        def OnInUseTimer(self,event):
            self.OnToggle(None)
    
        def OnQuit(self, event):
            self.RemoveIcon()
            wx.CallAfter(self.Destroy)
            self.frame.Close()
    
    if __name__ == '__main__':
        app = wx.App()
        frame=wx.Frame(None)
        TaskBarIcon(frame)
        app.MainLoop()
    

    and the images: toggle1.png toggle2.png

    In action: enter image description here