用点击反馈咆哮Python绑定?

用点击反馈咆哮Python绑定?,python,macos,pyobjc,growl,Python,Macos,Pyobjc,Growl,我试图使用GrowlPython绑定(Growl存储库中的Growl.pyv0.7)来编写一个小应用程序。当前缺少的一个特性是发送给Python的单击通知 我知道在Objective-C中,当用户单击通知时,它会向正在运行的应用程序发送一个触发器。我想对Python绑定做类似的事情。当用户单击通知时,我希望Python程序在浏览器中打开URL(或以另一种方式处理事件) 你有没有想过我该怎么做 更新:感谢synthesizerpatel提供了一个很有前途的解决方案,我相信他的话,它对Lion起到了

我试图使用GrowlPython绑定(Growl存储库中的Growl.pyv0.7)来编写一个小应用程序。当前缺少的一个特性是发送给Python的单击通知

我知道在Objective-C中,当用户单击通知时,它会向正在运行的应用程序发送一个触发器。我想对Python绑定做类似的事情。当用户单击通知时,我希望Python程序在浏览器中打开URL(或以另一种方式处理事件)

你有没有想过我该怎么做

更新:感谢synthesizerpatel提供了一个很有前途的解决方案,我相信他的话,它对Lion起到了作用。不幸的是,我开始淡出Mac,所以我不再做太多Mac编程了。尽管如此,我还是做了一些调试,因为它在雪豹上仍然不起作用,原因如下:

这就是你想要的吗

#!/usr/bin/env python 
#
# pyGrr!
#
# This code was originally found @
# http://www.cocoaforge.com/viewtopic.php?f=6&t=13359&p=91992&hilit=pyobjc+growl
# It is (to the best of our knowledge) the work of user 'tooru' on the same
# website.
#
# I make no claim to this code, all I did was get it working with PyObjC on Lion
# reformatted it a bit and added some more verbose explanations of what the script
# does. To be honest, I haven't touched pyobjc in a couple years and I was amazed
# that it still works! Even more amazed that I was able to get this example working
# in about 20 minutes.
#
# Great job tooru! 
# 
#   I have verified this code works with the following combination of 
#   packages / versions
#
#   * OSX Lion 10.7.3
#   * Python 2.7
#   * Growl 1.3
#   * Growl SDK 1.3.1
#
# 
# - Nathan Ramella nar@hush.com (http://www.remix.net)
##################################################################################

import objc
from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper
import time
import sys
import os

myGrowlBundle = objc.loadBundle(
  "GrowlApplicationBridge",
  globals(),
  bundle_path = objc.pathForFramework(
    '/Library/Frameworks/Growl.framework'
  )
)

class MenuMakerDelegate(NSObject):

  """
  This is a delegate for Growl, a required element of using the Growl
  service.

  There isn't a requirement that delegates actually 'do' anything, but
  in this case, it does. We'll make a little menu up on the status bar
  which will be named 'pyGrr!'

  Inside the menu will be two options, 'Send a Grr!', and 'Quit'. 

  Send a Grr! will emit a growl notification that when clicked calls back
  to the Python code so you can take some sort of action - if you're that
  type of person.
  """

  statusbar = None
  state = 'idle'

  def applicationDidFinishLaunching_(self, notification):

    """
    Setup the menu and our menu items. Getting excited yet?
    """

    statusbar = NSStatusBar.systemStatusBar()
    # Create the statusbar item
    self.statusitem = statusbar.statusItemWithLength_(NSVariableStatusItemLength)

    self.statusitem.setHighlightMode_(1)  # Let it highlight upon clicking
    self.statusitem.setToolTip_('pyGrr!')   # Set a tooltip
    self.statusitem.setTitle_('pyGrr!')   # Set an initial title

    # Build a very simple menu
    self.menu = NSMenu.alloc().init()
    menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
      'Send a Grr!',
      'rcNotification:',
      ''
    )
    self.menu.addItem_(menuitem)

    # Default event
    menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
      'Quit',
      'terminate:',
      ''
    )
    self.menu.addItem_(menuitem)

    # Bind it to the status item
    self.statusitem.setMenu_(self.menu)

  def rcNotification_(self,notification):

    """
    This is run when you select the 'Send a Grr!' menu item. It 
    will lovingly bundle up a Grr and send it Growl's way.
    """

    print "Sending a growl notification at", time.time()

    GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(
      "Grr! - I'm a title!",
      "This is where you put notification information.",
      "test1",
      None,
      0,
      False,
      "this ends up being the argument to your context callback"
    )

class rcGrowl(NSObject):

  """
  rcGrowl registers us with Growl to send out Grrs on behalf
  of the user and do 'something' with the results when a 
  Grr has been clicked.

  For additional information on what the what is going on
  please refer to the growl dox @ 

  http://growl.info/documentation/developer/implementing-growl.php
  """

  def rcSetDelegate(self):
    GrowlApplicationBridge.setGrowlDelegate_(self)

  def registrationDictionaryForGrowl(self):

    """
    http://growl.info/documentation/developer/implementing-growl.php#registration
    """

    return {
      u'ApplicationName'    :   'rcGrowlMacTidy',
      u'AllNotifications'   :   ['test1'],
      u'DefaultNotifications' :   ['test1'],
      u'NotificationIcon'   :   None,
    } 

  # don't know if it is working or not
  def applicationNameForGrowl(self):
    """ 
    Identifies the application.
    """
    return 'rcGrowlMacTidy'

  #def applicationIconDataForGrowl(self):
    """
    If you wish to include a custom icon with the Grr,
    you can do so here. Disabled by default since I didn't
    want to bloat up this up
    """
    #icon = NSImage.alloc().init()
    #icon = icon.initWithContentsOfFile_(u'remix_icon.tiff')
    #return icon

  def growlNotificationWasClicked_(self, ctx):

    """
    callback for onClick event
    """
    print "we got a click! " + str(time.time()) + " >>> " + str(ctx) + " <<<\n"

  def growlNotificationTimedOut_(self, ctx):

    """ 
    callback for timing out
    """
    print "We timed out" + str(ctx) + "\n"

  def growlIsReady(self):

    """
    Informs the delegate that GrowlHelperApp was launched
    successfully. Presumably if it's already running it
    won't need to run it again?
    """
    print "growl IS READY"


if __name__ == "__main__":

  # Both 'growlnotify' and this script seem to have the following
  # error after emitting a Grr!
  #
  # Error Domain=GCDAsyncSocketErrorDomain Code=4 "Read operation timed out" 
  # UserInfo=0x7fa444e00070 {NSLocalizedDescription=Read operation timed out}
  # 
  # So, we redirect stderr to /dev/null so that it doesn't muck up
  # the output of this script. Some folks say upgrading Growl fixes it,
  # others still have the problem. Doesn't seem to make much of a difference
  # one way or another, things still seem to work regardless.

  fp = os.open('/dev/null', os.O_RDWR|os.O_CREAT, 0o666)
  dupped = os.dup(2)
  os.dup2(fp, 2)

  # set up system statusbar GUI
  app = NSApplication.sharedApplication()
  delegate = MenuMakerDelegate.alloc().init()
  app.setDelegate_( delegate )

  # set up growl delegate
  rcGrowlDelegate=rcGrowl.new()
  rcGrowlDelegate.rcSetDelegate()
  AppHelper.runEventLoop()
#/usr/bin/env python
#
#皮格尔!
#
#此代码最初是找到的@
# http://www.cocoaforge.com/viewtopic.php?f=6&t=13359&p=91992&hilit=pyobjc+咆哮
#(据我们所知)这是用户“tooru”在同一平台上的工作
#网站。
#
#我对这段代码没有任何要求,我所做的只是让它在Lion上与PyObjC一起工作
#重新格式化了一点,并添加了一些关于脚本内容的详细解释
#是的。说实话,我已经好几年没碰过pyobjc了,我很惊讶
#它仍然有效!更让我惊讶的是,我能够让这个例子起作用
#大约20分钟后。
#
#干得好,图鲁!
# 
#我已经验证了此代码与以下组合的
#软件包/版本
#
#*OSX Lion 10.7.3
#*Python 2.7
#*咆哮1.3
#*咆哮SDK 1.3.1
#
# 
#-内森·拉梅拉nar@hush.com (http://www.remix.net)
##################################################################################
导入objc
从基础进口*
从AppKit导入*
从PyObjCTools导入AppHelper
导入时间
导入系统
导入操作系统
myGrowlBundle=objc.loadBundle(
“成长应用桥”,
globals(),
bundle_path=objc.pathForFramework(
“/Library/Frameworks/Growl.framework”
)
)
类MenuMakerDelegate(NSObject):
"""
这是咆哮的委托,咆哮是使用咆哮的必要元素
服务
没有要求学员实际“做”任何事情,但是
在这种情况下,是的。我们将在状态栏上创建一个小菜单
将命名为“pyGrr!”
菜单中有两个选项,“发送Grr!”和“退出”。
发送一个Grr!将发出一个咆哮通知,当单击该通知时,它将回调
这样你就可以采取一些行动了——如果你是这样的话
类型的人。
"""
状态栏=无
状态='空闲'
def applicationdFinishLaunching(自我,通知):
"""
设置菜单和我们的菜单项。兴奋了吗?
"""
statusbar=NSStatusBar.systemStatusBar()
#创建状态栏项
self.statusitem=statusbar.statusItemWithLength(NSVariableStatusItemLength)
self.statusitem.setHighlightMode(1)#单击后使其高亮显示
self.statusitem.setToolTip_u2;(“pyGrr!”)#设置工具提示
self.statusitem.setTitle(('pyGrr!')#设置初始标题
#建立一个非常简单的菜单
self.menu=NSMenu.alloc().init()
menuitem=NSMenuItem.alloc().initWithTitle\u action\u key等效_(
“发送Grr!”,
“通知:”,
''
)
self.menu.addItem(菜单项)
#默认事件
menuitem=NSMenuItem.alloc().initWithTitle\u action\u key等效_(
“退出”,
“终止:”,
''
)
self.menu.addItem(菜单项)
#将其绑定到状态项
self.statusitem.setMenu(self.menu)
def rcNotification(自我通知):
"""
当您选择“发送Grr!”菜单项时,将运行此操作。它将
将可爱地捆绑一个Grr,并发送它咆哮的方式。
"""
打印“在发送咆哮通知”,time.time()
GrowlApplication Bridge.notifyWithTitle\u description\u notificationName\u iconData\u priority\u isSticky\u clickContext_(
“Grr!-我是头衔!”,
“这是您放置通知信息的位置。”,
“测试1”,
没有一个
0,
假,,
“这最终成为上下文回调的参数”
)
类rcGrowl(NSObject):
"""
rcGrowl向CROWL注册,代表我们发送GRR
当
Grr已被单击。
有关正在进行的操作的更多信息
请参阅咆哮声dox@
http://growl.info/documentation/developer/implementing-growl.php
"""
def rcSetDelegate(自我):
GrowlApplicationBridge.setgrowlelegate(self)
def注册字典FORGROWL(自我):
"""
http://growl.info/documentation/developer/implementing-growl.php#registration
"""
返回{
u'ApplicationName':'rcgrowlactidy',
u'AllNotifications':['test1'],
u'DefaultNotifications':['test1'],
u'NotificationIcon':无,
} 
#不知道它是否有效
def应用程序名FORROWL(自身):
""" 
标识应用程序。
"""
返回“rcgrowlactidy”
#def应用程序数据行(自身):
"""
如果您希望在Grr中包含自定义图标,
你可以在这里这样做。默认情况下禁用,因为我没有
想把这个弄肿吗
"""
#icon=NSImage.alloc().init()
#icon=icon.initWithContentsOfFile(u'remix\u icon.tiff'))
#返回图标
def增长通知已单击(自身,ctx):
"""
onClick事件的回调
"""

打印“我们点击了!”+str(time.time())+“>>>”+str(ctx)+“这里运气好吗?我也很想知道。你是想让它捕捉所有的咆哮通知,还是仅仅是一个能够发送咆哮通知的python应用程序,当用户将其解职时,它能够捕捉鼠标点击?主要是python应用程序。为了它的价值(对谁来说