The next widget in our discussion today is GtkVBox. As I mentioned in the previous post, GtkVBox is one of the Layout Container, which is to contain one or more child widgets and arrange them in a certain order as well, specifically, GtkVBox arranges child widgets in column order.
Let's look at the reference first:
+ Reference to GtkVBox
+ Reference to GtkBox
As you see in the hierarchy, GtkVBox is inherited from GtkBox; hence, it's a GtkBox as well. We will need to apply characteristics of GtkBox to GtkVBox; simply, use a GtkVBox as a GtkBox.
First, we need to create a GtkVBox (vertical layout)
GtkWidget * gtk_vbox_new ( gboolean homogeneous, gint spacing );
So, if I want to create a VBox and share the same space allotments for all children w/ 10 pixels spacing between them, the code will be:
GtkWidget *vbox;
vbox = gtk_vbox_new( TRUE, 10 );
Next is to add children to the box layout. Since GtkVBox is a vertical layout manager, therefore, every elements added to the layout will be in this order.
In layout container, the step or method of adding more child widgets is so called "Pack".
If you pay attention to the reference manual, there are 2 methods to pack child:
void gtk_box_pack_start(
GtkBox *box,
GtkWidget *child,
gboolean expand,
gboolean fill,
guint padding );
void gtk_box_pack_end(
GtkBox *box,
GtkWidget *child,
gboolean expand,
gboolean fill,
guint padding );
You may wonder what the differences in pack_start and pack_end are?
The explanation is simple, since it's like a column, you can either specify to pack child from top to bottom or vice versa.
If you want to pack child from top to bottom, use gtk_box_pack_start(). The first child will be at the top, the next child will be arranged below the previous one....and so on.
The same w/ gtk_box_pack_end() if you want to pack from bottom to top.
Well, not much to say about layout. You can find out more information that you need on reference manual.
Let's do a simple Gtk application w/ GtkVBox.
Practice 1: A Gtk application with a label and an Exit button packed in GtkVBox.
You'd better code first then look at my source to make sure you're fine.
/*
* @author [JaPh]
* @date August 08, 2009
* @file GtkVBoxp_01.c
* @site http://xjaphx.blogspot.com/
*/
/* HEADER */
#include <gtk/gtk.h>
#include <glib.h>
/* EVENT */
void
button_clicked_event( GObject *button, gpointer data )
{
gtk_main_quit();
}
/* MAIN */
int
main( int argc, char *argv[] )
{
/* 1. declare widgets */
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *button;
GtkWidget *label;
/* 2. init gtk app */
gtk_init( &argc, &argv );
/* 3. init all widgets */
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW( window ), "[JaPh]Lesson 4: GtkVBox" );
gtk_widget_set_size_request( window, 200, 200 );
/* 3a. create new vbox widget */
vbox = gtk_vbox_new( FALSE, 10 );
label = gtk_label_new("Click Exit button to exit.");
button = gtk_button_new_with_label("Exit");
/* 3b. add child widgets to vbox from top to bottom */
gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 10 );
gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 10 );
/* 4. add vbox to main window */
gtk_container_add( GTK_CONTAINER( window ), vbox );
/* 5. signal connect */
g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( button_clicked_event ), NULL );
/* 6. show window */
gtk_widget_show_all( window );
/* 7. activate gtk app */
gtk_main();
/* 8. return code */
return 0;
}
Practice 2: Make an Gtk application w/ a GtkLabel to hold an integer value, one GtkButton click to increase value, one GtkButton click to decrease value; the last button to exit program.
/*
* @author [JaPh]
* @date August 08, 2009
* @file GtkVBoxp_02.c
* @site http://xjaphx.blogspot.com/
*/
/* HEADER */
#include <gtk/gtk.h>
/* FUNCTION DEF. */
static int counter = 0;
void
btn_inc_clicked_event( GtkButton *btn_inc, GtkLabel *label )
{
++counter;
gchar counter_buf[10];
g_snprintf( counter_buf, 9, "%d", counter );
gtk_label_set_text( label, counter_buf );
}
void
btn_dec_clicked_event( GtkButton *btn_dec, GtkLabel *label )
{
--counter;
gchar counter_buf[10];
g_snprintf( counter_buf, 9, "%d", counter );
gtk_label_set_text( label, counter_buf );
}
/* MAIN */
int
main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *btn_inc, *btn_dec, *btn_exit;
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW( window ), "[JaPh]Lesson 4: GtkVBox" );
gtk_widget_set_size_request( window, 200, 200 );
vbox = gtk_vbox_new( TRUE, 5 );
label = gtk_label_new("0");
btn_inc = gtk_button_new_with_mnemonic("I_ncrease");
btn_dec = gtk_button_new_with_mnemonic("D_ecrease");
btn_exit = gtk_button_new_with_mnemonic("E_xit");
/* packing */
gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 5 );
gtk_box_pack_start( GTK_BOX( vbox ), btn_inc, FALSE, FALSE, 5 );
gtk_box_pack_start( GTK_BOX( vbox ), btn_dec, FALSE, FALSE, 5 );
gtk_box_pack_start( GTK_BOX( vbox ), btn_exit, FALSE, FALSE, 5 );
gtk_container_add( GTK_CONTAINER( window ), vbox );
/* signal & event */
g_signal_connect( GTK_BUTTON( btn_inc ), "clicked",
G_CALLBACK( btn_inc_clicked_event ), GTK_LABEL( label ) );
g_signal_connect( GTK_BUTTON( btn_dec ), "clicked",
G_CALLBACK( btn_dec_clicked_event ), GTK_LABEL( label ) );
g_signal_connect( GTK_BUTTON( btn_exit ), "clicked",
G_CALLBACK( gtk_main_quit ), NULL );
g_signal_connect_swapped( G_OBJECT( window ), "destroy",
G_CALLBACK( gtk_main_quit ), NULL );
gtk_widget_show_all( window );
gtk_main();
return 0;
}
Take your time to practice and do more exercises from your already-known GtkWidget.
Have fun!@