25

After having spent quite some time looking at ways to an app for the menu bar we're close to admit defeat.

We are basically just looking for an example/pointer on how to create an app that will put itself in the menu bar (the small icons next to the clock), and have a menu. Nothing fancy at all.

It feels like something that should be very easy to do, but we haven't been able to find an example that works.

Maybe it's not possible with Python? Does anyone know how others do it?

talonmies
  • 70,661
  • 34
  • 192
  • 269
freeall
  • 3,187
  • 4
  • 24
  • 31
  • Possibly a related question: http://stackoverflow.com/questions/3104818/cross-platform-python-gui-suitable-for-taskbar-win-and-menubar-mac-functiona –  Dec 17 '11 at 13:51
  • 1
    How about [pyObjC](http://pyobjc.sourceforge.net/)? – talonmies Dec 17 '11 at 14:13
  • Thanks talonmies! I am having problems installing it though. Tried easy_install, but failed. Then I downloaded the source and tried to compile it (python 2.7.1), but I get this error: error: Could not find suitable distribution for Requirement.parse('pyobjc-framework-ServiceManagement==2.4a0'). Seems like this might require some work. – freeall Dec 18 '11 at 12:55
  • Found out! Should not install it. Python already have it. – freeall Dec 19 '11 at 12:31
  • See this related question: http://stackoverflow.com/questions/141432/how-can-i-create-a-status-bar-item-with-cocoa-and-python-pyobjc – Pierz Mar 30 '17 at 10:42

3 Answers3

37

An option would be to use rumps which provides a level of abstraction on top of PyObjC. I wrote it specifically for quickly generating these types of simple status bar apps.

I hope that this could help a few people out there looking for a simple, semantic solution!

A short example snippet follows. Decorators are used for registering functions as callbacks for click events and timers. There is also support for 10.8 notifications.

import rumps

class AwesomeStatusBarApp(rumps.App):
    def __init__(self):
        super(AwesomeStatusBarApp, self).__init__("Awesome App")
        self.menu = ["Preferences", "Silly button", "Say hi"]

    @rumps.clicked("Preferences")
    def prefs(self, _):
        rumps.alert("jk! no preferences available!")

    @rumps.clicked("Silly button")
    def onoff(self, sender):
        sender.state = not sender.state

    @rumps.clicked("Say hi")
    def sayhi(self, _):
        rumps.notification("Awesome title", "amazing subtitle", "hi!!1")

if __name__ == "__main__":
    AwesomeStatusBarApp().run()

pic

Jared
  • 25,627
  • 7
  • 56
  • 61
  • I tried running the sample code in the readme and all the menu items except "Quit" are disabled. Unless I add setAction_ explicitly, the menuitems are disabled. Is this the expected behaviour? – Pradeep Vairamani Jul 16 '14 at 11:12
  • I had to do `port install py-pip && pip install pyobjc rumps` to get the example to work. Thanks! – e40 Nov 29 '15 at 16:25
12

wxPython won't be able to add a taskbar item. You can do this by instead using PyObjC like so:

from AppKit import NSStatusBar
status_item = NSStatusBar.systemStatusBar().statusItemWithLength_(-1) #NSVariableStatusItemLength
status_item.setImage_(<NSImage instance to status icon>)

Just refer to the NSStatusItem class reference to do stuff to the item, e.g. add a menu, change the highlight image, etc.

maranas
  • 1,396
  • 1
  • 12
  • 21
  • 1
    hi freeall, if you're using python 2.6 and up, i think an easy_install of pyobjc will work just fine, but I suggest you not do this - OSX comes bundled with pyobjc (I'm not sure with Lion; if it doesn't have it, you can just go ahead with the easy_install). test you default Python if it has it installed by importing objc or AppKit – maranas Dec 18 '11 at 14:36
  • Thanks so much! That was a few hours lost yesterday, then :) I am usually programming in JavaScript (NodeJS) so I forgot that Python is "batteries included". – freeall Dec 19 '11 at 12:30
  • Note to self: _always read all the comments first_. I (unknowingly) removed the 'included' installation when pyobjc-core wouldn't compile, so now I'm stuck re-installing even though it was there all along. – Joost Aug 27 '13 at 17:08
0

Actually, you can use wxPython. Refer to my related answer here: how to set a menubar icon on mac osx using wx

Generic Ratzlaugh
  • 717
  • 1
  • 6
  • 13