Search code examples
pythonpython-2.7gtkgtk3gobject

Custom signal not propagating


For a project I working on I'm using custom signals which are emitted on a child and then should propagate to it parent when the signal is not handle completely.

Based on the information I could find it seems that not having a handler connected (using connect) or returning False in the callback should allow the signal to propagate to the widgets parent.

Yet in my toy example below this doesn't work:

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)

        GObject.signal_new("print-this", GObject.TYPE_OBJECT, GObject.SIGNAL_RUN_LAST, GObject.TYPE_BOOLEAN, [GObject.TYPE_STRING])

        self.button = Gtk.Button.new_with_label("Emit signals")
        self.button.connect("clicked", self.emit_signals)

        self.frame = Gtk.Frame.new("Some frame")
        self.frame.add(self.button)
        self.add(self.frame)

        self.connect("print-this", self.got_it)
        self.show_all()
        Gtk.main()

    def got_it(self, widget, string):
        print string
        return False

    def emit_signals(self, *args):
        print "Emitting signals.."
        self.button.emit("print-this", "I was emitted from the button")
        time.sleep(1)
        self.frame.emit("print-this", "I was emitted from the frame")
        time.sleep(1)
        self.emit("print-this", "I was emitted from the window")

When the signals are emitted I would expect the prints from all three emits yet I only get the print for the emit on the window. Which is probably caused by the fact that the signal is not propagating at all.

So where am I going wrong here? And more important how can I achieve the propagating behavior I'm looking for?


Solution

  • Generic GObject signals do not propagate through the GTK widget tree. Only event-related signals do that, and it's done internally inside GTK.

    If you want your signal to be recursively emitted you'll have to add a function that calls g_signal_emit() on every widget inside the tree.