GNOME Bugzilla – Bug 579345
GtkBuilder should support objects with duplicate names
Last modified: 2014-08-21 17:47:11 UTC
Please describe the problem: I used glade-3 to convert a libglade file to gtkbuilder format. Glade-3 reported no errors or problems. I then tried to use the result and received three errors that I do not fully understand how to fix: $ python Python 2.6.2c1 (release26-maint, Apr 14 2009, 08:02:48) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import gtk >>> x.add_from_file('/tmp/test.glade') __main__:1: GtkWarning: Unknown property: GtkEntry.group __main__:1: Warning: IA__g_object_set_valist: invalid object type `GtkEntry' for value type `GtkRadioButton' __main__:1: GtkWarning: gtk_button_box_set_child_secondary: assertion `child->parent == GTK_WIDGET (widget)' failed 1L Steps to reproduce: 1. startup glade 3 2. open libglade file 3. edit the preferences and change them to gtkbuilder, 2.12 4. save the file 5. try to load it in an interactive python session Actual results: I receive these errors: __main__:1: GtkWarning: Unknown property: GtkEntry.group __main__:1: Warning: IA__g_object_set_valist: invalid object type `GtkEntry' for value type `GtkRadioButton' __main__:1: GtkWarning: gtk_button_box_set_child_secondary: assertion `child->parent == GTK_WIDGET (widget)' failed Expected results: I would not expect these errors. Does this happen every time? yes Other information:
Created attachment 132848 [details] Original libglade file Original libglade file, before conversion
Created attachment 132849 [details] gtkbuilder file, converted from mergedata.glade original libglade file converted to gtkbuilder format
I think this is somehow a bug in GtkBuilder. You have a radio button called title1, and an entry called title1, seems Glade kept the names intact, and followed a naming policy where names are unique to a toplevel. Seems builder is trying to assign your entry which is also named title1 as a radio group member. Try renaming the entry (or chose a project-wide naming policy from the prefs dialog) and see if builder eats it up.. and then we can move this bug to GTK+:GtkBuilder
I changed the naming policy to project-wide and now I receive no errors upon x.add_from_file. Does that mean that this is really a gtkbuilder problem?
I believe so, I'll forward it to the builder product and see if Johan objects to this being a requirement of GtkBuilder, or at least a good rfe The problem here is that you have conflicting widget names, in seperate hierarchies in the same file, GtkBuilder, when searching for object properties; should search for objects inside the immediate hierarchy first, before defaulting to searching the whole tree (this ofcourse demands that object property loading be deffered until the file finishes loading...)
Yes, I agree with your reasoning. In my case, I have a number of old libglade files where they were used like this: x = glade.XML('foobar.glade", "foo", "bar") but this sort of syntax is not supported in the python bindings for gtkbuilder (is it?) I'm not sure if this was (is) common practice, but it is heavily used in the project I'm trying to convert. So in the libglade days, no problem since I just parsed part of the file. In the brave new world I have a problem (several actually). Perhaps there are fellow-sufferers out there.
For what it's worth, the problem I am experiencing could be alleviated if the Gtk objects implemented the get_object method, which could be used to search for a child object by name. I wrote the following Python function: def get_object(self,value): if self.get_name() == value: return self elif hasattr(self,'get_children'): for child in self.get_children(): object = get_object(child, value) if object is not None: break return object return None and added it to my Gtk object like this: builder = gtk.Builder() builder.add_from_file('my.glade') window = builder.get_object('window1') window.get_object = get_object At this point, I can search for an object by name within the GtkWindow object. That is fine for the moment and I can use this approach as a workaround. My question is: "Would you please consider adding the get_object method to the Gtk objects?" (I suppose if it were added to gtk.Container, it would be inherited by the children.)
I'd rather have globally unique names. Thats why I made GtkBuilder reject non-unique names.
I think the only problem this presents is conversion complexities. I agree its not a needed feature to support duplicate names, when you need a bunch of dialogs that all have the same "display-label" or whatnot, you can have them in separate files and load them at will. People who have this obstacle could currently do the following: - Convert the file to builder format in Glade - Create separate glade files for the dialogs with conflicting names and copy the dialogs individually to their own files - Load multiple files with GtkBuilder for multiple uis instead of one. Depending on what you decide, I can try to lock down a project wide naming policy when converting to builder format in Glade (at least showing a list of conflicting names at conversion time... for the next release cycle ofcourse...)
We could try something like automatically prefixing non-unique names with the name of the toplevel that they're contained in, but then you have to be careful to fix up references. In general, I'd like to keep these kinds of guessing games out of libgtk itself. Whether to stick them inside glade or gtk-builder-convert, I don't have a preference...
Just to be clear, its one GtkBuilder object that should have unique widget names ? one ui... ? (certainly not across an entire GTK+ application...) Currently I think one GtkBuilder can manage adding multiple uis which may have conflicting names, but each file having unique names in the project, its the callers responsibility to call gtk_builder_get_object() for each object they need before the next call to gtk_builder_add_from_file(). Maybe the _add_from_file() or _get_object() api docs should make a note about this fact... Builder could also offer some management (at least a lookup) on a per-ui basis, i.e. something like: int desc = gtk_builder_add_from_file(...) gtk_builder_get_object_from_ui (biulder, desc, "name")) ... hrm ... that could pave a road towards eventual support for UI merging from builder *cough* ...
(In reply to comment #8) > I'd rather have globally unique names. Thats why I made GtkBuilder reject > non-unique names. > I used gtkbuilder on a glade file with many duplicate names. They were not rejected. (At least I got no error messages to that effect) All that happened was that when I did a get_object for one of them it found the first occurrence, which is not always the right one in context. That's why I added the get_object method to my ui objects. Perhaps such a method should be there permanently?
I don't think we will change this at this point. However, GtkBuilder does allow unnamed objects nowadays, which helps greatly with avoiding duplicate names: only name the objects that you need to refer to.