安装最新的py2app,然后创建一个新目录 - cd 到它 - 在其中创建一个HelloWorld.py
文件,例如:
# generic Python imports
import datetime
import os
import sched
import sys
import tempfile
import threading
import time
# need PyObjC on sys.path...:
for d in sys.path:
if 'Extras' in d:
sys.path.append(d + '/PyObjC')
break
# objc-related imports
import objc
from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper
# all stuff related to the repeating-action
thesched = sched.scheduler(time.time, time.sleep)
def tick(n, writer):
writer(n)
thesched.enter(20.0, 10, tick, (n+1, writer))
fd, name = tempfile.mkstemp('.txt', 'hello', '/tmp');
print 'writing %r' % name
f = os.fdopen(fd, 'w')
f.write(datetime.datetime.now().isoformat())
f.write('\n')
f.close()
def schedule(writer):
pool = NSAutoreleasePool.alloc().init()
thesched.enter(0.0, 10, tick, (1, writer))
thesched.run()
# normally you'd want pool.drain() here, but since this function never
# ends until end of program (thesched.run never returns since each tick
# schedules a new one) that pool.drain would never execute here;-).
# objc-related stuff
class TheDelegate(NSObject):
statusbar = None
state = 'idle'
def applicationDidFinishLaunching_(self, notification):
statusbar = NSStatusBar.systemStatusBar()
self.statusitem = statusbar.statusItemWithLength_(
NSVariableStatusItemLength)
self.statusitem.setHighlightMode_(1)
self.statusitem.setToolTip_('Example')
self.statusitem.setTitle_('Example')
self.menu = NSMenu.alloc().init()
menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
'Quit', 'terminate:', '')
self.menu.addItem_(menuitem)
self.statusitem.setMenu_(self.menu)
def writer(self, s):
self.badge.setBadgeLabel_(str(s))
if __name__ == "__main__":
# prepare and set our delegate
app = NSApplication.sharedApplication()
delegate = TheDelegate.alloc().init()
app.setDelegate_(delegate)
delegate.badge = app.dockTile()
delegate.writer(0)
# on a separate thread, run the scheduler
t = threading.Thread(target=schedule, args=(delegate.writer,))
t.setDaemon(1)
t.start()
# let her rip!-)
AppHelper.runEventLoop()
当然,在您的真实代码中,您将每 3 分钟执行一次自己的周期性操作(而不是像我在这里那样每 20 秒编写一个临时文件),执行您自己的状态更新(而不仅仅是显示一个计数器到目前为止写入的文件数量)等等,但我希望这个示例向您展示了一个可行的起点。
然后在 Terminal.App cd 到包含这个源文件的目录,py2applet --make-setup HelloWorld.py
, python setup.py py2app -A -p PyObjC
。
您现在在子目录中dist
有一个目录HelloWorld.app
;open dist
并将图标拖到 Dock 上,一切就绪(在您自己的机器上 - 由于-A
标志,分发到其他机器可能无法正常工作,但没有它我在构建时遇到了麻烦,可能是由于错误安装的 egg 文件在这台机器周围;-)。毫无疑问,您会想要自定义您的图标 &c。
这并不能满足您要求的“额外功劳”——它已经有很多代码了,我决定在这里停下来(额外功劳可能需要一个新问题)。此外,我不太确定我在这里执行的所有咒语是否真的是必要的或有用的;根据您的要求,这些文档非常适合在没有 Xcode 的情况下制作 pyobjc .app,因此我从网上找到的示例代码的点点滴滴以及大量的试验和错误中将其组合在一起。不过,我希望它有所帮助!-)