GObject.add_emission_hook работает только один раз

Я хочу использовать GObject.add_emission_hook для подключения, чтобы поймать сигнал всех экземпляров класса. Вроде работает, но только один раз. В приведенном ниже минимальном примере «сигнал получен» печатается только один раз, независимо от того, сколько раз была нажата одна из кнопок. Почему так и как я могу получать сигнал о каждом клике?

Конечно, в моих приложениях все сложнее, и получатель (здесь класс Foo) не знает объекты, излучающие сигналы. Поэтому подключение к сигналам самих объектов невозможно.

from gi.repository import Gtk
from gi.repository import GObject

class MyWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Hello World")
        vbox = Gtk.VBox()
        self.add(vbox)
        button = Gtk.Button(label="Click Here")
        vbox.pack_start(button, True, True, 0)
        button = Gtk.Button(label="Or There")
        vbox.pack_start(button, True, True, 0)
        self.show_all()

class Foo:

    def __init__(self):
        GObject.add_emission_hook(Gtk.Button, "clicked", self.on_button_press)

    def on_button_press(self, *args):
        print "signal received"


win = MyWindow()
foo = Foo()
Gtk.main()

person uuazed    schedule 07.07.2012    source источник


Ответы (1)


Вы должны вернуть True из обработчика событий, чтобы обратные вызовы запускались для последовательных событий. Если вы возвращаете False (когда вы ничего не возвращаете, я предполагаю, что возвращается False), то хук удаляется. Это можно проиллюстрировать следующим примером на основе вашего образца:

from gi.repository import Gtk
from gi.repository import GObject

class MyWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Hello World")
        vbox = Gtk.VBox()
        self.add(vbox)
        self.connect("destroy", lambda x: Gtk.main_quit())
        button = Gtk.Button(label="Click Here")
        vbox.pack_start(button, True, True, 0)
        button = Gtk.Button(label="Or There")
        vbox.pack_start(button, True, True, 0)
        self.show_all()

class Foo:
    def __init__(self):
        self.hook_id = GObject.add_emission_hook(Gtk.Button, "button-press-event", self.on_button_press)
        GObject.add_emission_hook(Gtk.Button, "button-release-event", self.on_button_rel)

    def on_button_press(self, *args):
        print "Press signal received"
        return False # Hook is removed

    def on_button_rel(self, *args):
        print "Release signal received"
        # This will result in a warning
        GObject.remove_emission_hook(Gtk.Button, "button-press-event",self.hook_id)
        return True


win = MyWindow()
foo = Foo()
Gtk.main()

Надеюсь это поможет!

person another.anon.coward    schedule 07.07.2012
comment
возврат True решает проблему! Так сложно (невозможно) найти такие вещи в документации gtk. Спасибо! - person uuazed; 08.07.2012