2

ドックアイコンなどを備えた非常に基本的な Cocoa アプリケーションを作成したい場合は、Xcode と GUI ビルダー (w/ PyObjC )を使用する必要があるようです。

私が書こうとしているアプリケーションは、主にアルゴリズムと基本的な IO に関係しているため、Apple 固有のものとはほとんど関係がありません。

基本的に、アプリケーションは定期的に (たとえば、3 分ごとに) 実行されることになっています。AppleScript を介して情報を取得し、HTML ファイルを特定のディレクトリに書き込みます。このアプリケーションに Dock アイコンを追加したいと思います.. 主にプロセスの「ステータス」を表示します (たとえば、エラーがある場合.. Dock アイコンには赤いフラグが付きます)。ドック アイコンのもう 1 つの利点は、起動時に実行できることです。

ドックの右クリック メニューを簡単な方法で定義するための追加ボーナス (例: Python の callable リストを使用)。

Xcode または GUI ビルダーを使用せずに、単に Emacs と Python を使用してこれを達成できますか?

4

3 に答える 3

9

最新の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 秒ごとに一時ファイルを書き込むのではなく)、独自のステータス更新を行います (単にカウンターを表示するのではなく)これまでに書き込まれたファイルの数など)などですが、この例が実行可能な出発点を示していることを願っています.

py2applet --make-setup HelloWorld.py次に、Terminal.App cd で、このソース ファイルを含むディレクトリに移動しますpython setup.py py2app -A -p PyObjC

サブディレクトリdistにディレクトリがありHelloWorld.appます。open distアイコンをDockにドラッグすると、すべて設定されます(自分のマシンで-フラグが原因で他のマシンへの配布が機能しない場合がありますが-A、おそらく誤ってインストールされたeggファイルが敷設されたため、フラグなしでビルドするのに苦労しましたこのマシンの周り;-)。アイコン &c をカスタマイズしたくなることは間違いありません。

これは、あなたが求めた「余分なクレジット」を行いません-それはすでに多くのコードであるため、ここで停止することにしました(余分なクレジットは、新しい質問を正当化する可能性があります)。また、ここで実行しているすべての呪文が実際に必要または有用であるかどうかはよくわかりません。ドキュメントは、必要に応じて、Xcode を使用せずに pyobjc .app を作成するのにかなり寛大です。そのため、ネット上で見つかったサンプル コードの断片とかなりの量の試行錯誤からこれをハッキングしました。それでも、私はそれが役に立てば幸いです!-)

于 2009-10-04T23:18:09.780 に答える
2

Mac OS X 10.5 および 10.6 に含まれているPyObjCは、探しているものにかなり近いものです。

于 2009-10-04T21:01:12.303 に答える
0

チャックはPyObjCについて正しいです。

次に、このNSApplicationメソッドについて読んで、アイコンを変更する必要があります。

-(void)setApplicationIconImage:(NSImage *)anImage;

ドックメニューの場合は、アプリケーションデリゲートで以下を実装します。NSMenuをプログラムで構築して、InterfaceBuilderの使用を回避できます。

-(NSMenu *)applicationDockMenu:(NSApplication *)sender;

于 2009-10-04T23:01:10.957 に答える