[Glade-users] Separation between GUI and main

Igor Chetverovod chetverovod at gmail.com
Sat Jan 21 05:31:52 UTC 2012


Hello Tristan,

Could you please to provide more detailed example for this part of your letter:
"...Better practice still, is to derive a GtkContainer for every modular
GUI object which can be used and reused throughout your GUI..."  ?

I am not novice in using of GTK and glade, but I did not catch the
work flow of mentioned new technic. It would be great to see a pice of
code.

Thank you,

Igor

2012/1/20, Tristan Van Berkom <tristan.van.berkom at gmail.com>:
> On Sat, Jan 21, 2012 at 12:44 AM, Manuel Ferrero <mferrero at reer.it> wrote:
>> I'm learning GTK+ and Glade on my win32 machine.
>>
>> Right now I was able to write, compile and run a simple code with a
>> window,
>> an hbox and a toggle button in it.
>> When the user presses the button I display the state of the button via the
>> callback function.
>>
>> The main function is this:
>>
>> ---SNIP---
>> int main(int argc, char *argv[])
>> {
>> gtk_init(&argc, &argv);
>>
>> GtkBuilder *builder_handler;
>> GtkWidget *window;
>> GtkWidget *connect_button;
>>
>> builder_handler = gtk_builder_new();
>> gtk_builder_add_from_file(builder_handler, GUI_XML_FILENAME, NULL);
>>
>> window = GTK_WIDGET(gtk_builder_get_object(builder_handler, "window"));
>> connect_button = GTK_WIDGET(gtk_builder_get_object(builder_handler,
>> "connect_button"));
>>
>> gtk_builder_connect_signals(builder_handler, NULL);
>> g_object_unref (G_OBJECT (builder_handler));
>>
>> gtk_widget_show (connect_button);
>> gtk_widget_show (window);
>>
>>
>> gtk_main ();
>>
>> return 0;
>> }   // main
>> ---PINS---
>>
>> I'll spare you the callbacks.
>>
>> Now my question is this: with Glade I add another button (expanding the
>> hbox
>> of course) and I name it my_button_2.
>> The code has to know about this new button so at least I have to declare a
>> new GtkWidget pointer, call the gtk_builder_get_object() to assing the
>> pointer and then show it with a gtk_widget_show().
>> Leave alone the callbacks for all the signals.
>>
>> I don't understand how this can separate the GUI from the code.
>> Am I missing something?
>> Is tehre some way to connect signals without knowing the objects? In this
>> case I could only write the needed callbacks to manage the new button.
>
> If you need to control the state of a widget in the interface, you need
> a pointer to that widget.
>
> If you add a widget to your interface, say a button that causes a new
> action you need to handle, then you don't need a pointer to that button.
>
> A common practice is to use the last argument of
> gtk_builder_connect_signals(),
> you can create a data structure which contains the needed pointers for your
> whole module, i.e.
>
> typedef struct _MyModule {
>    GtkWidget *the_toggle_button;
>    GtkWidget *the_entry;
>    GtkWidget *the_toplevel_window;
>    GtkWidget *etc, *etc;
> };
>
> {
>    MyModule module = { 0, };
>
>    /* where you load the gui file */
>    builder = gtk_builder_new ();
>    gtk_builder_add_from_file (...);
>
>    module.the_toggle_button = gtk_builder_get_object (builder,
> "the-toggle-button");
>    ... etc etc ...
>
>    /* then just pass your main module structure to all of your callback */
>    gtk_builder_connect_signals (builder, &module);
> }
>
> This is common practice but still old-fashioned if you ask me.
>
> Better practice still, is to derive a GtkContainer for every modular
> GUI object which can be used and reused throughout your GUI.
>
> Then you repeat the above exercise in the object's ->constructed()
> method, pass the object's instance as the user data for all callbacks
> and have one GtkBuilder xml definition for each composite object
> which you might use in your GUI.
>
> You might have a GUI file describing the layout of your preferences
> dialog, your project properties dialog etc.
>
> Then if you are developing an editor program which might have
> multiple projects loaded, you might be allowed to display project
> properties dialogs for different projects at the same time.
>
> Then your properties dialog (which derives from GtkDialog and
> has it's contents defined by a GtkBuilder xml file which is added
> to the dialog at ->constructor() time)... would have a "project"
> property.
>
> At which point, creating a preferences dialog can be done
> at any time with a call to:
>   new_dialog = g_object_new (MY_TYPE_CUSTOM_PROPERTIES_DIALOG,
>                                                  "project",
> the_project_to_display_properties_for,
>                                                  NULL);
>
> Admittedly, with this paradigm, you shouldnt really have to be
> doing things by hand in your ->constructor() method... or
> accessing GtkBuilder apis manually at all... this is just because
> we have not yet landed something at the GtkContainer level
> to allow you to simply assign GtkBuilder xml to a container class
> (in other words, we are actually still a step behind NextStep
> in this respect).
>
> To answer your question about "separating your GUI from your code",
> of course you will always need to declare object members for the
> widgets that you actually need to access, adding these members
> only ever happens when your program gains new features, and
> those features require interaction with the GUI.
>
> In earlier times, GUIs were constructed in actual code, i.e.:
>
>    window = gtk_window_new();
>    box = gtk_box_new (...);
>    gtk_widget_show (box);
>    gtk_container_add (GTK_CONTAINER (window), box);
>
>    /* ... huge code to construct menu bar  ... */
>    gtk_widget_show (menubar);
>    gtk_container_add (GTK_CONTAINER (box), menubar);
>
>    /* huge code to construct the rest of your application... etc etc */
>
> In the first versions of Glade, it was only possible to use with code
> generation,
> this ended up in the mixing of business logic in generated C code
> files, rendering
> it virtually impossible to ever modify your GUI after you initially
> developped it
> (or just very very impractical, because then you have to re-merge in all of
> your business logic... just because you wanted to add some icon to a menu
> item or add some alignment to a frame or whatever minor detail you wanted
> to change).
>
> Using xml to define the actual interface makes UI coding practical and
> maintainable, it separates the files in which you store your code and the
> files in which you store your interface definition (note also that you can
> always put your GtkBuilder xml into a header file as a string constant
> as a step in your compilation, and include the GtkBuilder xml if you
> are not content with accessing the hard-drive just to fire up a new
> dialog... or if you just want to avoid the complexity of resolving system
> installation paths at runtime).
>
> Cheers,
>            -Tristan
>
>> Please remember I'm really new to this programming style, I'm an embedded
>> C
>> programmer so I know nealry nothign about objects and events.
>>
>> Thanks in advance.
>> --
>> Regards,
>> Manuel Ferrero
>> R&D department
>>
>> Reer SpA
>> Tel.  +39 011 2482215
>> Fax. +39 011 859867
>>
>> L'utilizzo non autorizzato del presente messaggio e' vietato e potrebbe
>> costituire reato.
>> Se il presente messaggio non e' a Lei indirizzato, il suo contenuto non
>> deve
>> essere considerato
>> come trasmesso o autorizzato dalla Reer SpA; in tale caso Le saremmo grati
>> se, via e-mail,
>> ce ne comunicasse l'errata ricezione.
>>
>> The unauthorized use of this e-mail is prohibited and could constitute an
>> offence.
>> If you are not the intended recipient of this message its contents shall
>> be
>> understood as neither
>> given nor endorsed by Reer SpA. Please notify Reer SpA by e-mail
>> immediately
>> in that case.
>>
>> _______________________________________________
>> Glade-users maillist  -  Glade-users at lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/glade-users
> _______________________________________________
> Glade-users maillist  -  Glade-users at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/glade-users
>


More information about the Glade-users mailing list