GNOME Bugzilla – Bug 122654
gobject.type_register effectively doesn't work
Last modified: 2006-01-09 14:11:27 UTC
You'll recognise the error from the changelog in the patch below. Has anyone ever properly tested gobject.type_register with __gsignals__? It just doesn't work for me. In the patch I will post below, I try to fix this. However, it doesn't fix the problem completely, and I honestly don't know how to solve this. We are trying to emit signals in self->obj, but such signals may be registered in another class. I get this warning: [spectrum:console]$ ./numexp-console ** Message: registering signal 'completion' for gtype Numexp_Console+entry+CompletionSelector ** Message: registering signal 'completion': 91 <GType Numexp_Console+entry+CompletionSelector (135959536)> iid=OAFIID:Numexp_ConsoleView ..... (later, when the signal is emitted) .... (numexp-console:13438): GLib-GObject-WARNING **: gsignal.c:1755: signal id `91' is invalid for instance `0x832ce40' Advice is much appreciated.... what a complicated problem :(
Created attachment 20061 [details] [review] partial fix
Ok, so now I changed the way I initilize the object. Now it works, but I get the following error when the object is GCed: GLib-GObject-CRITICAL **: file gobject.c: line 1338 (g_object_unref): assertion `object->ref_count > 0' failed Here's my derived class. Notice how I now call gobject.GObject.__init__ instead of gtk.Window.__init__. PS: this is still with my patch applied. class CompletionSelector(gtk.Window): __gsignals__ = { "completion": (gobject.SIGNAL_RUN_LAST, # signal flags None, # return type [str] # param types ) } def __init__(self, completions): #gtk.Window.__init__(self, gtk.WINDOW_POPUP) gobject.GObject.__init__(self, type=gtk.WINDOW_POPUP) frame = gobject.new(gtk.Frame, shadow=gtk.SHADOW_ETCHED_OUT, visible=True) self.add(frame) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.show() frame.add(sw) liststore = gtk.ListStore(gobject.TYPE_STRING) for comp in completions: iter = liststore.append() liststore.set(iter, 0, comp) self.treeview = gtk.TreeView(liststore) self.treeview.set_property("headers-visible", False) renderer = gtk.CellRendererText() renderer.set_property("xalign", 0.0) column = self.treeview.insert_column_with_attributes( -1, "Completions", renderer, text=0) sw.add(self.treeview) self.treeview.show() self.connect("key-press-event", self.__key_press) self.treeview.connect("row_activated", self.__row_activated) def __key_press(self, widget, event): if event.state == 0 and event.keyval == gtk.keysyms.Escape: self.destroy() def __row_activated(self, tree, path, column): model = tree.get_model() iter = model.get_iter(path) if iter is None: return completion = model.get_value(iter, 0) self.emit("completion", completion) self.destroy() # class_init gobject.type_register(CompletionSelector)
Ok, taking jdahlin's hint and looking at the signal example in pygtk source dir, I got it working correctly without any patch. It seems I had to call self.__gobject_init__(type=gtk.WINDOW_POPUP). Well, marking as NOTABUG, but I think pygtk has a lot of traps that shouldn't be there. Why isn't gtk.Window.__init__ chained to gobject.GObject.__init__ chained to __gobject_init__? That would be the only truly pythonic way. Not to mention the gobject.type_register... :/