Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a status bar item with Cocoa and Python (PyObjC)?

I have created a brand new project in XCode and have the following in my AppDelegate.py file:

from Foundation import *
from AppKit import *

class MyApplicationAppDelegate(NSObject):
    def applicationDidFinishLaunching_(self, sender):
        NSLog("Application did finish launching.")

        statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
        statusItem.setTitle_(u"12%")
        statusItem.setHighlightMode_(TRUE)
        statusItem.setEnabled_(TRUE)

However, when I launch the application no status bar item shows up. All the other code in main.py and main.m is default.

like image 306
davidmytton Avatar asked Sep 26 '08 19:09

davidmytton


2 Answers

The above usage of .retain() is required because the statusItem is being destroyed upon return from the applicationDidFinishLaunching() method. Bind that variable as a field in instances of MyApplicationAppDelegate using self.statusItem instead.

Here is a modified example that does not require a .xib / etc...

from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper

start_time = NSDate.date()


class MyApplicationAppDelegate(NSObject):

    state = 'idle'

    def applicationDidFinishLaunching_(self, sender):
        NSLog("Application did finish launching.")

        self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
        self.statusItem.setTitle_(u"Hello World")
        self.statusItem.setHighlightMode_(TRUE)
        self.statusItem.setEnabled_(TRUE)

        # Get the timer going
        self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_(start_time, 5.0, self, 'tick:', None, True)
        NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode)
        self.timer.fire()

    def sync_(self, notification):
        print "sync"

    def tick_(self, notification):
        print self.state


if __name__ == "__main__":
    app = NSApplication.sharedApplication()
    delegate = MyApplicationAppDelegate.alloc().init()
    app.setDelegate_(delegate)
    AppHelper.runEventLoop()
like image 84
brandon Avatar answered Nov 15 '22 13:11

brandon


I had to do this to make it work:

  1. Open MainMenu.xib. Make sure the class of the app delegate is MyApplicationAppDelegate. I'm not sure if you will have to do this, but I did. It was wrong and so the app delegate never got called in the first place.

  2. Add statusItem.retain() because it gets autoreleased right away.

like image 44
Chris Lundie Avatar answered Nov 15 '22 11:11

Chris Lundie