Базовое приложение для какао, использующее док в Python, но не Xcode и все остальное - PullRequest
2 голосов
/ 05 октября 2009

Похоже, что если я хочу создать очень простое приложение Cocoa со значком дока и т. П., Мне придется использовать Xcode и конструктор GUI (w / PyObjC ).

Приложение, которое я намереваюсь написать, в основном связано с алгоритмами и базовым вводом-выводом - и, таким образом, в основном не связано с конкретными вещами Apple.

По сути, приложение должно запускаться периодически (скажем, каждые 3 минуты). Получать некоторую информацию через AppleScript и записывать HTML-файлы в определенный каталог. Я хотел бы добавить значок Dock для этого приложения .. в основном для отображения «статуса» процесса (например, если есть ошибка. Значок Dock будет иметь красный флаг). Еще одним преимуществом иконки док-станции является то, что я могу запустить ее при запуске.

Дополнительный бонус за простое определение контекстного меню правой кнопкой мыши (например, использование списков вызываемых в Python).

Могу ли я добиться этого без использования Xcode или сборщиков графического интерфейса, а просто с помощью Emacs и Python?

Ответы [ 3 ]

8 голосов
/ 05 октября 2009

Установите последнюю версию py2app , затем создайте новый каталог - перейдите к нему - в нем создайте файл 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 перейдите в каталог, содержащий этот исходный файл, py2applet --make-setup HelloWorld.py, python setup.py py2app -A -p PyObjC.

Теперь у вас есть в подкаталоге dist каталог HelloWorld.app; open dist и перетащите значок в Dock, и все готово (на вашем собственном компьютере - распространение на другие машины может не работать из-за флага -A, но у меня возникли проблемы с его сборкой, возможно, из-за неправильно установленные файлы яиц, лежащие вокруг этой машины ;-). Без сомнения, вы захотите настроить свою иконку & c.

Это не делает "лишний кредит", который вы просили, - это уже много кода, и я решил остановиться на этом (дополнительный кредит может оправдать новый вопрос). Кроме того, я не совсем уверен, что все заклинания, которые я здесь выполняю, действительно необходимы или полезны; Документы довольно удобны для создания pyobjc .app без Xcode, как вам нужно, поэтому я взломал это вместе из кусочков примера кода, найденного в сети, плюс значительное количество проб и ошибок. Тем не менее, я надеюсь, что это помогает! -)

2 голосов
/ 05 октября 2009

PyObjC , который входит в Mac OS X 10.5 и 10.6, очень близок к тому, что вы ищете.

0 голосов
/ 05 октября 2009

Чак прав насчет PyObjC.

Затем вы должны прочитать об этом методе NSApplication, чтобы изменить свой значок.

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

Для меню док-станции выполните следующее в делегате приложения. Вы можете создать NSMenu программно, чтобы избежать использования InterfaceBuilder.

- (NSMenu *) applicationDockMenu: (NSApplication *) отправитель;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...