Cross-Window Communication

only for RuBoard - do not distribute or recompile

Cross-Window Communication

This next example will revisit the method of the Getting Cross-Window Widgets to Communicate example from Chapter 5. The fundamental problem is this: In a given window widget, or form, the child widgets do not know about the existence of other child widgets in other forms. Therefore, what is needed is a way to get the child widgets in one form to be able to send information to and receive information from the child widgets in other forms. Recall from Chapter 5 that the way to do this is to first make the forms global in scope and then use Glade s lookup_widget() function to find the child widget when you re given the form widget. (Again, refer to the section Getting Cross-Window Widgets to Communicate, in Chapter 5.) At this point, however, there is one thing that needs to be mentioned: The Glade interface builder, that is, the part that writes the interface.c file, connects the child widgets to the parent widgets automatically. So it is already done for you in the example from Chapter 5. In this example, however, because interface.c is not going to be used, those connections have to be put into the code manually. cross-window.glade is created by the Save button in Glade.

The example below is called cross-window and can be downloaded from the companion Web site (www.newriders.com).

First, open Glade and create two identical windows , as shown in Figure 14.5. The widget tree shows the structure of the two windows .

Figure 14.5. cross-window.glade as built with Glade.
graphics/14fig05.gif

Listing 14.3 contains the cross-window.glade file. Again, this is to show the structure displayed in Figure 14.5.

Listing 14.3 cross-window.glade
 <?xml version="1.0"?>  <GTK-Interface>  <project>    <name>cross-window</name>    <program_name>cross-window</program_name>    <directory></directory>    <source_directory>src</source_directory>    <pixmaps_directory>pixmaps</pixmaps_directory>    <language>C</language>    <gnome_support>False</gnome_support>    <gettext_support>False</gettext_support>    <use_widget_names>False</use_widget_names>    <output_main_file>False</output_main_file>    <output_support_files>False</output_support_files>    <output_build_files>False</output_build_files>    <backup_source_files>True</backup_source_files>    <main_source_file>interface.c</main_source_file>    <main_header_file>interface.h</main_header_file>    <handler_source_file>callbacks.c</handler_source_file>    <handler_header_file>callbacks.h</handler_header_file>    <support_source_file>support.c</support_source_file>    <support_header_file>support.h</support_header_file>    <translatable_strings_file></translatable_strings_file>  </project>  <widget>    <class>GtkWindow</class>    <name>window1</name>    <signal>      <name>delete_event</name>      <handler>quit_application</handler>      <last_modification_time>Wed, 21 Mar 2001 11:14:55 GMT</last_modification_time>    </signal>    <title>window1</title>    <type>GTK_WINDOW_TOPLEVEL</type>    <position>GTK_WIN_POS_NONE</position>    <modal>False</modal>    <allow_shrink>False</allow_shrink>    <allow_grow>True</allow_grow>    <auto_shrink>False</auto_shrink>    <widget>      <class>GtkVBox</class>      <name>vbox1</name>      <homogeneous>False</homogeneous>      <spacing>0</spacing>      <widget>        <class>GtkEntry</class>        <name>entry1</name>        <can_focus>True</can_focus>        <editable>True</editable>        <text_visible>True</text_visible>        <text_max_length>0</text_max_length>        <text></text>        <child>          <padding>0</padding>        <expand>False</expand>        <fill>False</fill>        </child>      </widget>      <widget>        <class>GtkButton</class>        <name>button1</name>        <can_focus>True</can_focus>        <signal>        <name>clicked</name>        <handler>button1_clicked</handler>        <last_modification_time>Wed, 21 Mar 2001 11:08:25 GMT</last_modification_time>        </signal>        <label>Send to Window 2</label>        <child>        <padding>0</padding>        <expand>False</expand>        <fill>False</fill>        </child>      </widget>      <widget>        <class>GtkLabel</class>        <name>label1</name>        <label></label>        <justify>GTK_JUSTIFY_CENTER</justify>        <wrap>False</wrap>        <xalign>0.5</xalign>        <yalign>0.5</yalign>        <xpad>0</xpad>        <ypad>0</ypad>        <child>        <padding>0</padding>        <expand>False</expand>        <fill>False</fill>        </child>      </widget>    </widget>  </widget>  <widget>    <class>GtkWindow</class>    <name>window2</name>    <signal>      <name>delete_event</name>      <handler>quit_application</handler>      <last_modification_time>Wed, 21 Mar 2001 11:15:07 GMT</last_modification_time>    </signal>    <title>window2</title>    <type>GTK_WINDOW_TOPLEVEL</type>    <position>GTK_WIN_POS_NONE</position>    <modal>False</modal>    <allow_shrink>False</allow_shrink>    <allow_grow>True</allow_grow>    <auto_shrink>False</auto_shrink>    <widget>      <class>GtkVBox</class>      <name>vbox2</name>      <homogeneous>False</homogeneous>      <spacing>0</spacing>      <widget>        <class>GtkEntry</class>        <name>entry2</name>        <can_focus>True</can_focus>        <editable>True</editable>        <text_visible>True</text_visible>        <text_max_length>0</text_max_length>        <text></text>        <child>        <padding>0</padding>        <expand>False</expand>        <fill>False</fill>        </child>      </widget>      <widget>        <class>GtkButton</class>        <name>button2</name>        <can_focus>True</can_focus>        <signal>        <name>clicked</name>        <handler>button2_clicked</handler>        <last_modification_time>Wed, 21 Mar 2001 11:08:11 GMT</last_modification_time>        </signal>        <label>Send to Window 1</label>        <child>        <padding>0</padding>        <expand>False</expand>        <fill>False</fill>        </child>      </widget>      <widget>        <class>GtkLabel</class>          <name>label2</name>        <label></label>        <justify>GTK_JUSTIFY_CENTER</justify>        <wrap>False</wrap>        <xalign>0.5</xalign>        <yalign>0.5</yalign>        <xpad>0</xpad>        <ypad>0</ypad>        <child>        <padding>0</padding>        <expand>False</expand>        <fill>False</fill>        </child>      </widget>    </widget>  </widget>  </GTK-Interface> 

Cross-window has two forms, each of which has a three-row vertical packing box containing an entry widget, a command button, and a label widget.

The application should work in such a way that if the user types something in the entry box of window1 and clicks the Send to Window 2 command button also in window1, the text in window1 will be displayed in the label widget in window2. Figure 14.6 shows cross-window running.

Figure 14.6. Cross-window communication.
graphics/14fig06.gif

Next, examine the code for cross-window.c in Listing 14.4.

Listing 14.4 cross-window.c
 #ifdef HAVE_CONFIG_H  #  include <config.h>  #endif  #include <gtk/gtk.h>  #include <glade/glade.h>  #include "support.h"  GtkWidget *window1;  GtkWidget *window2;  void button1_clicked()  {    GtkWidget *txt;     gchar *txt1;     g_print("button1_clicked...\n");  /* Retrieve the text in the entry widget of the form   * that holds the button that was clicked.   */  txt = lookup_widget(window1, "entry1");     txt1 = gtk_editable_get_chars(GTK_EDITABLE(txt), 0, -1);     g_print("%s\n", txt1);  /* Push the retrieved text from above to the label widget of   * the other window.   */  gtk_label_set_text(GTK_LABEL(lookup_widget(window2, "label2")), txt1);  }  void button2_clicked()  {    GtkWidget *txt;     gchar *txt2;  /*  button2_clicked  has the same structure as  button1_clicked.  * However, the target widgets are different.   */  g_print("button2_clicked...\n");     txt = lookup_widget(window2, "entry2");       txt2 = gtk_editable_get_chars(GTK_EDITABLE(txt), 0, -1);     g_print("%s\n", txt2);     gtk_label_set_text(GTK_LABEL(lookup_widget(window1, "label1")), txt2);  }  void quit_application()  {  /* The glade XML file identifies this function with the delete-event   * for both window1 and window2.   */  gtk_main_quit();  }  int main (int argc, char *argv[])  {   GladeXML *xml;    gtk_init (&argc, &argv);    glade_init();  /* window1 */  xml = glade_xml_new("cross-window.glade", "window1");    if (!xml)       {        g_print("unable to load interface window1...\n");         return 1;       }    window1 = glade_xml_get_widget(xml, "window1");  /* Link the called widgets to the window widget so that   * the called widgets can be retrieved with a  lookup_widget()  * call.   */  gtk_object_set_data_full(GTK_OBJECT(window1), "entry1",                             glade_xml_get_widget(xml, "entry1"), 0L);    gtk_object_set_data_full(GTK_OBJECT(window1), "label1",                             glade_xml_get_widget(xml, "label1"), 0L);  /* Connect the signals to their handlers, as defined in the   * .glade file.   */  glade_xml_signal_autoconnect(xml);  /* In window2, the code structure is the same as that above,   * except that the widgets in question are different.   */  xml = glade_xml_new("cross-window.glade", "window2");    if (!xml)       {        g_print("unable to load interface window2...\n");         return 1;       }    window2 = glade_xml_get_widget(xml, "window2");    gtk_object_set_data_full(GTK_OBJECT(window2), "entry2",                             glade_xml_get_widget(xml, "entry2"), 0L);    gtk_object_set_data_full(GTK_OBJECT(window2), "label2",                             glade_xml_get_widget(xml, "label2"), 0L);    glade_xml_signal_autoconnect(xml);  /* Finally, show the two window widgets. */  gtk_widget_show (window1);    gtk_widget_show (window2);    gtk_main ();    return 0;  } 

The button1_clicked() , button2_clicked() , and quit_application() functions come before main() ”each of which is simple enough. main() is not fundamentally different from the previous example, except that now there are two form widgets to set up and the gtk_object_set_data_full() calls. The purpose of these calls is to connect the child label and entry widgets with their parent window widgets in such a way that the lookup_widget() function in support.c can find all the widgets correctly. The lookup_widget() function used here is the same as that shown in Chapter 5, Listing 5.5, in lines 25 through 47.

Finally, to compile the application, enter the following command from the project subdirectory:

 % gcc -Wall `gtk-configcflagslibs` *.c -o cross-window -lglade 
only for RuBoard - do not distribute or recompile


MySQL Building User Interfaces
MySQL: Building User Interfaces (Landmark)
ISBN: 073571049X
EAN: 2147483647
Year: 2001
Pages: 119

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net