Re: GtkBuilder and widget names



On Sat, Dec 24, 2011 at 1:23 AM, George Brink <siberianowl yahoo com> wrote:
> Well, right now I am using these names to identify visual objects in a
> unified way.
> For example, I have a set of check-boxes which are part of my "Options"
> dialog. Obviously, I need to remember those settings between each program
> run. So instead of dealing with each and every check-box individually, and
> writes dozens of callbacks, I have a code like this:
>
>
> extern GtkBuilder *builder;
> extern GKeyFile *settings;    // myapp.ini
> extern gboolean flag1, flag2; // some global options
>
> struct Widgets_Flags {
>        gchar *name; gboolean *flag;
> } flags[] = { {"chk1", &flag1}, {"chk2", &flag2}};
>
> for(i=0; i<sizeof(flags)/sizeof(flags[0]); i++) {
>  GtkWidget *w = GTK_WIDGET(
>                gtk_builder_get_object(builder, flags[i].name)
>                                );
>  if(!w)
>        g_critical("Panic! UI does not have object %s!", flags[i].name);
>
>  gboolean check = g_key_file_get_boolean(settings, "main",
>                //gtk_widget_get_name(w));
>                // now it is replaced with
>                gtk_buildable_get_name(GTK_BUILDABLE(w)));
>
>  g_signal_connect(G_OBJECT(w), "toggled",
>                G_CALLBACK(toggled_option_checkbox), flags[i].flag);
> }
>
> // And a similar code for the callback itself:
> void toggled_option_checkbox(GtkCheckMenuItem *checkMenuItem,
>                                 gpointer *data) {
>  gboolean *flag = (gboolean *) data;
>  *flag = gtk_check_menu_item_get_active(checkMenuItem);
>  g_key_file_set_boolean(settings, "main",
>        gtk_buildable_get_name(GTK_BUILDABLE(checkMenuItem)),
>        *flag);
> }
>
> And that is the whole code to deal with boolean flags in the "Option
> Dialog".
>
> The point is, now I do not need to keep a dictionary to translate between
> the widget's ID as it is defined in the Glade editor and the text name for
> the same option as it would be stored in the settings file.
> The transition between widget, variable in memory, and serialized variable
> become much easier.

For what it's worth, I see your point, and I don't consider your code to be
messy or obfuscated in any way for that, however it's a sort of API abuse.

You will have the limitation that your settings keys must not conflict in name
with any other widget names in your project, which is probably not an
issue for you
in any case.

On the other hand, an elegant and more extendable solution would be to:
   o Start by subclassing a GtkBox class
   o Design the contents of your key-editing widget to be a label on
the left, and
      possibly a toggle button on the right
   o Add few properties to your MyKeyEditor class
       - "group-name"
       - "key-name"
       - "title"
   o Possibly you will use a global/singleton GKeyFile for your
application which
      can be accessed in your application with my_configuration_file_get()

In your implementation of MyKeyEditor, which is only responsible for
editing a single
key, you would:
   o Update the GtkLabel on the left hand side of your editor to
reflect the "title" property
      string at any time my_key_editor_set_title() is called (i.e.
whenever the "title" property
      changes).
   o When the user presses the toggle button, you would go ahead and
update the boolean
      value of "key-name" in the group "group-name" in the global
GKeyFile that your application
      keeps track of
   o The application might choose to dump the keyfile to disk at
whatever time it chooses, perhaps
      when the app's settings dialog closes or when the application quits.

Additionally with this approach with is a bit more object oriented,
you could go ahead and:
   o Create a generalized "changed" signal emitted by your editor
class, this can be used
      to propagate setting changed state throughout the program in a uniform way
   o Or better yet, you use a GtkAction type of approach, have a
GObject which is shared
      with your MyKeyEditor widgets as well as exported to other parts
of your app which are
      interested in receiving setting change notifications, they would
pull it from the abstract
      'action' instead.

   o You also get to easily extend this api to support additional
setting types, i.e. integer types
      and string types can also be saved to your key file by simply
using separate implementations
      of the same MyKeyEditor api... cleanly and without changing any api

   o You can also easily add your custom widget to Glade's palette and
design your settings
      dialog by adding a handful of your custom editor widgets and
configuring each of them
      with the human readable 'title' property, and the 'group-name'
and 'key-name' properties
      which control what part of the key file to update.

Of course if you only need a quick and dirty dialog that works quickly
for a smallish app
that wont incur you a huge maintenence cost in the future, you
probably want to skip all
of these design details, but for a larger scale app which you intend
to be maintaining and
updating for years to come, you will definitely prefer to design
things in a more object
oriented fashion, i.e. at least have an extendable concept and api for
'what is a key editor'.

Best Regards,
            -Tristan

>
>
> On 12/23/2011 1:44 AM, Tristan Van Berkom wrote:
>>
>> Yes it's intended.
>>
>> There is a way to access the name of the widget key in the builder file,
>> however I've always been a little ticked about that.
>>
>> Can you name me one use case of how that would be useful ?
>>
>> I think gtk_buildable_get_name() will return what you want, but
>> again... is there any reason why GTK+ should have that api ?
>>
>> Cheers,
>>              -Tristan
>>
>> On Fri, Dec 23, 2011 at 7:46 AM, George Brink<siberianowl yahoo com>
>>  wrote:
>>>
>>> I draw an UI in Glade, loaded it in with the GtkBuilder object.
>>> Now I am accessing one widget in this UI:
>>> ---
>>> GtkWidget *w = gtk_builder_get_object(builder, "obj1");
>>> g_message(gtk_widget_get_name(w));
>>> ----
>>> This prints GtkLabel, instead of obj1. Why? Is it intended behavior?
>>> How can I read "obj1" from the w?
>>>
>>> _______________________________________________
>>> gtk-list mailing list
>>> gtk-list gnome org
>>> http://mail.gnome.org/mailman/listinfo/gtk-list
>
>
>
> _______________________________________________
> gtk-list mailing list
> gtk-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-list


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]