Обратный вызов не вызывается с действием уведомления pygobject

Я хочу отобразить кнопку в уведомлении с помощью pygobject. Эта кнопка должна вызывать обратный вызов при нажатии, но этого не происходит, и я не понимаю, почему.

Вот мой код:

from gi.repository import Notify, Gtk

class Test:
    def __init__(self):
        Notify.init('example')
        self.notif()

        Gtk.main()

    def notif(self):
        notif = Notify.Notification.new('Title', 'something','dialog-information')

        notif.add_action('display', 'Button', self.callback, None)
        notif.show()

    def callback(self, notif_object, action_name, users_data):
        print("Work!")
        Gtk.main_quit()

Test()

Когда я нажимаю на кнопку "Кнопка", ничего не происходит и обратный вызов не вызывается. В чем проблема ?

После некоторых попыток я обнаружил, что когда я ставлю Gtk.main() сразу после notif.show(), обратный вызов работает. Но я не могу использовать это решение, поскольку оно означает, что я не могу показывать другие уведомления позже.


person arthropode    schedule 11.02.2015    source источник


Ответы (2)


Вам нужно удерживать ссылку на ваш объект уведомления до тех пор, пока не будет вызван обратный вызов:

from gi.repository import Gtk, Notify


class Window(Gtk.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        Notify.init('Test')
        self.notification = None

        self.set_border_width(5)

        self.button = Gtk.Button('Test')

        self.box = Gtk.Box()
        self.box.pack_start(self.button, True, True, 0)
        self.add(self.box)

        self.button.connect('clicked', self.on_button)
        self.connect('delete-event', Gtk.main_quit)
        self.show_all()

    def on_button(self, button):
        if self.notification:
            self.notification.close()
        self.notification = Notify.Notification.new('Test')
        self.notification.add_action('clicked', 'Action', self.callback)
        self.notification.show()

    def callback(self, notification, action_name):
        print(action_name)

win = Window()
Gtk.main()

Если вам нужно показать больше одного и того же уведомления, вам нужен список объектов уведомлений.

Пример без окон см. в этом ответе.

person Fenikso    schedule 29.09.2015

ОБНОВЛЕНИЕ

Кажется, вам не нужно звонить

Gdk.threads_init()

Не помню обстоятельств, при которых я проверял это, но мог бы поклясться, что это имело значение для меня.

Обновленный пример:

import sys

from gi.repository import Notify
from gi.repository import Gtk

if not Notify.init('Notification Test'):
    print("ERROR: Could not init Notify.")
    sys.exit(1)

notification = Notify.Notification.new(
    "Notification Title",
    "Message...")

notification.set_urgency(Notify.Urgency.NORMAL)
def actionCallback(notification, action, user_data = None):
    print("Callback called:"+action)
    Gtk.main_quit()

notification.add_action("test-action", "Test Action", actionCallback)

if not notification.show():
    print("ERROR: Could not show notification.")
    sys.exit(2)

Gtk.main()
person olivervbk    schedule 06.08.2015
comment
Gdk.threads_init() на самом деле не нужен в PyGObject 3.10.2+. Ваш пример работает, потому что вы все еще держите ссылку на notification при вызове Gtk.main() и не решаете проблему, с которой сталкивается OP. - person Fenikso; 29.09.2015