Работа с Центром уведомлений Mountain Lion с использованием PyObjC

Я пытаюсь отправлять уведомления в Mountain Lion из своего скрипта Python и реагировать на клики по уведомлениям. Отправка уведомлений работает отлично. Но все же мне не удалось заставить Lion отозвать мой скрипт по щелчку.

Вот что я делаю. Я реализовал класс уведомлений. Единственная цель экземпляра этого класса — предоставлять уведомления, вызывая notify(). В том же методе я устанавливаю объект делегата приложения.

import Foundation
import objc
import AppKit

class MountainLionNotification(Foundation.NSObject, Notification):

    def notify(self, title, subtitle, text, url):
        NSUserNotification = objc.lookUpClass('NSUserNotification')
        NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
        notification = NSUserNotification.alloc().init()
        notification.setTitle_(str(title))
        notification.setSubtitle_(str(subtitle))
        notification.setInformativeText_(str(text))
        notification.setSoundName_("NSUserNotificationDefaultSoundName")
        notification.setUserInfo_({"action":"open_url", "value":url})
        AppKit.NSApplication.sharedApplication().setDelegate_(self)
        NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)

    def applicationDidFinishLaunching_(self, sender):
        userInfo = sender.userInfo()
        if userInfo["action"] == "open_url":
            import subprocess
            subprocess.Popen(['open', userInfo["value"]])

Теперь я ожидал, что applicationDidFinishLaunching_() будет вызываться при нажатии на уведомление. К сожалению, этого никогда не происходит. Что я делаю неправильно?


person koloman    schedule 30.08.2012    source источник
comment
Я безуспешно пытался добавить декоратор @objc.signature("v@:^@") в метод делегата.   -  person koloman    schedule 31.08.2012
comment
Теперь я также попытался установить свой объект MountainLionNotification в качестве делегата центра уведомлений по умолчанию и реализовать метод протоколов userNotificationCenter_didActivateNotification_(). Все еще безуспешно!   -  person koloman    schedule 31.08.2012
comment
Удалось ли вам отображать уведомления только из скрипта/интерпретатора Python, не запуская цикл обработки событий? Кажется, я даже не могу получать уведомления, показывающие использование кода выше   -  person GP89    schedule 24.10.2012
comment
@ GP89 - вам обязательно нужно запустить цикл событий; нет никакого способа обойти это.   -  person Glyph    schedule 16.12.2012
comment
@koloman Откуда вы получили уведомление в классе MountainLionNotification (Foundation.NSObject, Notification)?   -  person Pylinux    schedule 20.05.2016
comment
если у вас есть ответ для Catalina, отправьте сообщение по адресу: stackoverflow.com/questions/62234033/   -  person Chromazmoves    schedule 10.06.2020


Ответы (1)


Хорошо, нашел. Не запускал AppHelper.runEventLoop(). Явно ошибка фейспалма. Работает следующий код:

class MountainLionNotification(Foundation.NSObject, Notification):

    def notify(self, title, subtitle, text, url):
        NSUserNotification = objc.lookUpClass('NSUserNotification')
        NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
        notification = NSUserNotification.alloc().init()
        notification.setTitle_(str(title))
        notification.setSubtitle_(str(subtitle))
        notification.setInformativeText_(str(text))
        notification.setSoundName_("NSUserNotificationDefaultSoundName")
        notification.setHasActionButton_(True)
        notification.setOtherButtonTitle_("View")
        notification.setUserInfo_({"action":"open_url", "value":url})
        NSUserNotificationCenter.defaultUserNotificationCenter().setDelegate_(self)
        NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)

    def userNotificationCenter_didActivateNotification_(self, center, notification):
        userInfo = notification.userInfo()
        if userInfo["action"] == "open_url":
            import subprocess
            subprocess.Popen(['open', userInfo["value"]])
person koloman    schedule 31.08.2012
comment
Я знаю, что это старо, но я получаю ошибки: objc.BadPrototypeError: Objective-C expects 1 arguments, Python argument has 5 arguments for <unbound selector notify of MountainLionNotification at 0x10bf48650> и Notification is not defined. Вы знаете, можно ли это исправить? - person themthem; 06.06.2020