Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mouse Events of WxPython TaskBarIcon on Mac OSX are not triggering

We are using TaskBarIcon of WxPython 2.9 on Mac OSX 10.8.5, currently we have a requirement to grab all Left, Right and Double Click Events when user clicks on TaskBarIcon of our Application. The problem we are having is that these events are not being triggered. Any help in this regard would be much appreciable.

This is the code we are using

import os
import sys
import wx

__author__ = 'Ammar Hasan'

CURRENT_ABSOLUTE_PATH = os.path.dirname(sys.argv[0])
TRAY_ICON = CURRENT_ABSOLUTE_PATH + "/resources/task_icon.ico"
TRAY_ICON_TOOLTIP = "UI Application"


ID_SHOW_OPTION = wx.NewId()
ID_EDIT_OPTION = wx.NewId()
ID_EXIT_OPTION = wx.ID_EXIT


class Icon(wx.TaskBarIcon):

    def __init__(self, parent, icon, tooltip):
        super(Icon, self).__init__(iconType=wx.TBI_CUSTOM_STATUSITEM)
        self.set_icon(icon, tooltip)
        self.parent = parent
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_icon_click)
        self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.on_icon_click)
        self.Bind(wx.EVT_MENU, self.menu_item_click)

    def get_menu(self):
        menu = wx.Menu()
        menu.Append(ID_SHOW_OPTION, "&Show Option 1")
        menu.Append(ID_EDIT_OPTION, "&Edit Option 2")
        menu.AppendSeparator()
        menu.Append(ID_EXIT_OPTION, "E&xit")
        return menu

    def on_icon_click(self, event):
        if event:
            print "Event Triggered."
        menu = self.get_menu()
        self.PopupMenu(menu)

    def menu_item_click(self, event):
        if event.Id == ID_SHOW_OPTION:
            pass
        elif event.Id == ID_EDIT_OPTION:
            pass
        else:
            self.parent.quit()

    def make_icon(self, img):
        """
        The various platforms have different requirements for the
        icon size...
        """
        if "wxMSW" in wx.PlatformInfo:
            img = img.Scale(16, 16)
        elif "wxGTK" in wx.PlatformInfo:
            img = img.Scale(22, 22)
        # wxMac can be any size upto 128x128, so leave the source img alone....
        icon = wx.IconFromBitmap(img.ConvertToBitmap())
        return icon

    def set_icon(self, path, tool_tip):
        image = wx.Image(path)
        icon = self.make_icon(image)
        self.SetIcon(icon, tool_tip)

    # def CreatePopupMenu(self, event=None):
    #     self.on_icon_click(event)


class Frame(wx.Frame):

    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs)
        self.app = wx.GetApp()
        self.icon = Icon(self, TRAY_ICON, TRAY_ICON_TOOLTIP)

    def quit(self):
        self.app.ExitMainLoop()

if __name__ == "__main__":
    app = wx.App()
    frame = Frame(None)
    frame.Show(False)
    app.SetTopWindow(frame)
    app.MainLoop()

N.B. We do not want to use CreatePopupMenu (because it is only triggered on Left Click), instead we want to grab all three specified mouse events.

like image 552
Ammar Hasan Avatar asked Jan 02 '14 13:01

Ammar Hasan


1 Answers

Taskbar icon implementation is OS dependent. The following app binds all events supplied in wxPython so you can use it for testing.

import wx
from wx.lib.embeddedimage import PyEmbeddedImage

task = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAArxJ"
    "REFUWIXl1z9oJGUYx/HPrvvP3SVmZYkkatYmJ1wTUmhp5YFFQC3kCq8RbAXBTrCxMoXClVdc"
    "JwtiZxfRQgsRRNJsSBMxiPljdkl2WZPMMtmsxb17SfbmcicIjvg0v3mf9/fOvO+X531nhv97"
    "ZCYTq6urc9BsNm/DxsbGq9Dtdqfg7OwsG1SSDofDK/ODwWAA/X6/BNl/fEl/My4SmIKlpaWf"
    "oFarXYM4jnG+gkk9PT29sn+svV4PtNvtS8/+1wnkxhf5fP5D2NvbG0Kr1foE4jg+gVwudxNq"
    "tVoe2u325xP3WoC5ublbsLOz823Ifx90THt4cVAqCOQgjuOXYXd396XQd3TRODU1dQNGo9FW"
    "SH08ca93IYqiW6H9ZdA7V00gFQTOwvXbQY+SjMVi8Xk4ODj48SH9Dc6rHp3HmUCqCOw+xPME"
    "HB8fPwuDweCPJFO5XJ6FQqEAeuON/4hIBYFHxRyUSqUc9Hq9RFKVSuUZyGTuH66JtTQZ/wkC"
    "81Aul8ftnSRTtVp9mvN3A6LHmUD6CVQqlRc4r278nuQrFAoVyGbvr2mY5JuM9BNoNBqvQxRF"
    "4/PityRfPp/PcmkXVJN8y8vLL8Lm5uavpJnAwsLCezAajd4KqfHKB0n+TCZzCMViEdTr9Teh"
    "0+n8HCwjaLVad2Fra+sN0khgcXHxHTg8PLzN+TdhJpP5JViKQS+RyOfz69Dv91+B+fn5D2Bl"
    "ZeUaNJvNJ2Ftbe25MOSMFBB44L+g0WisQ7vdvg6zs7Nge3v7DkRR9H6wXjrpZmZmbkC9Xv8a"
    "Op17nwNRdM82ro1ut/spxHH8ESkg8EANlEqlH2B6evo6HB0ddSCKomawJO6C/f39b6BarX4B"
    "xWLxJmSz2RGcnJx8BXEcfxaGnJACAg/UAOpBl4OuB10LeurqeCroa0H/DPrdRBspIPAXawn9"
    "rf2GhSwAAAAASUVORK5CYII=")

class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)

        self.tbicon = wx.TaskBarIcon()
        self.tbicon.SetIcon(task.GetIcon(), "Test")
        self.tbicon.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.LD)
        self.tbicon.Bind(wx.EVT_TASKBAR_LEFT_UP, self.LU)
        self.tbicon.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.RD)
        self.tbicon.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.RU)
        self.tbicon.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.LDC)
        self.tbicon.Bind(wx.EVT_TASKBAR_RIGHT_DCLICK, self.LDC)

        # This is a synonym for either wx.EVT_TASKBAR_RIGHT_DOWN 
        # or UP depending on the platform, use this event macro 
        # to catch the event which should result in the menu being 
        # displayed on the current platform.
        self.tbicon.Bind(wx.EVT_TASKBAR_CLICK, self.Click)

        self.Bind(wx.EVT_CLOSE, self.Cleanup)

        self.Show()

    def Click(self, e):
        print("Click")
        e.Skip()

    def LD(self, e):
        print("LD")
        e.Skip()

    def LU(self, e):
        print("LU")
        e.Skip()

    def RD(self, e):
        print("RD")
        e.Skip()

    def RU(self, e):
        print("RU")
        e.Skip()

    def LDC(self, e):
        print("L-DClick")
        e.Skip()

    def RDC(self, e):
        print("R-DClick")
        e.Skip()

    def Cleanup(self, e):
        self.tbicon.Destroy()
        wx.Exit()

app = wx.App(False)
win = MainWindow(None)
app.MainLoop()

On Windows 7, for example:

  • Left Down is emitted together with Left Up and not alone
  • Right Down is emitted correctly
  • Click is emitted with Right Up (Windows default for menu)
  • Double Clicks work just fine

If it does not work on OS X or the behavior you get seems to be wrong for your platform, consider reporting a bug at http://trac.wxwidgets.org/.

like image 193
Fenikso Avatar answered Oct 14 '22 12:10

Fenikso