Kontainer dan Peletakan Widget

Jika anda membuat aplikasi anda memerlukan beberapa widget. Pada contoh pertama, anda hanya membuat tiga widget, yang pertama adalah window utama (toplevel window). Kemudian label ditempatkan didalam button, dan button ditempatkan didalam window. Jadi anda mengetahui bahwa ada widget yang dapat dapat dimasukkan satu atau lebih widget lain.

Beberapa widget adalah turunan dari kelas abstrak GtkContainer sehingga dalam widget tersebut dapat ditempatkan widget lain, dalam konteks ini disebut widget kontainer. Terdapat beberapa widget kontainer yang khusus untuk menampung widget lain, seperti widget GtkVBox, GtkHBox dan GtkTable. Jika di dalam widget terdapat lebih dari satu widget bagaimana kita dapat mengatur posisi masing-masing widget. Peletakan dan pengaturan posisi widget dapat dilakukan dengan menggunakan beberapa fungsi, misalnya gtk_container_add() dan gtk_box_pack_start().


Contoh program, packing.c :

#include <gtk/gtk.h>

/* callback untuk mencetak ke stdout */
void callback( GtkWidget *widget,
gpointer data )
{
g_print ("Helo lagi – %s telah ditekan\n", (gchar *) data);
}

/* callback lain */
gint delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
gtk_main_quit ();
return FALSE;
}

int main( int argc,
char *argv[] )
{
/* Buat beberapa pointer dengan tipe GtkWidget */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;

/* Inisialisasi aplikasi GTK. Parameter yang dikenal oleh GTK
* akan diproses. */
gtk_init (&argc, &argv);

/* Buat window utama */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

/* Tulis “Box Horisontal” sebagai judul window */
gtk_window_set_title (GTK_WINDOW (window), “Boks Horisontal”);

/* fungsi delete_event sebagai pelaksana event “delete_event” */
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);

/* Set tebal batas window*/
gtk_container_set_border_width (GTK_CONTAINER (window), 10);

/* Buat boks horisontal, widget ini hanya sebagai penampung widget
* lain. Serta mengatur posisinya */
box1 = gtk_hbox_new (FALSE, 0);

/* Letakkan boks dalam window utama */
gtk_container_add (GTK_CONTAINER (window), box1);

/* Buat tombol “Tombol 1” */
button = gtk_button_new_with_label (“Tombol 1”);

/* Jika tombol ini ditekan, fungsi callback akan dipanggil dengan
* string “tombol 1” sebagai parameternya */
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (callback), (gpointer) "tombol 1");

/* Boks mempunyai fungsi tersendiri untuk menempatkan widget lain
* kedalamnya */
gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);

/* Setelah selesai dengan persiapannya tombol boleh ditampilkan */
gtk_widget_show (button);

/* Buat tombol kedua */
button = gtk_button_new_with_label ("Tombol 2");

/* fungsi yang sama dapat digunakan namun kali ini dengan parameter
* string “tombol 2” */
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (callback), (gpointer) "tombol 2");

gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);

/* tampilkan widget yang di dalam dahulu */
gtk_widget_show (button);

gtk_widget_show (box1);

gtk_widget_show (window);

/* Tunggu di dalam gtk_main, program siap menerima masukkan */
gtk_main ();

return 0;
}


Di sini Anda dapat melihat penggunaan GtkHBox, salah satu kontainer widget. Dua tombol kita masukkan ke dalamnya. Coba kompilasi dan jalankan programnya. Kemudian coba merubah ukuran windownya. Terlihat kedua tombol mengikuti perubahan window.

Sebagai latihan :

- ganti

box1 = gtk_hbox_new (FALSE, 0);

dengan

box1 = gtk_vbox_new (FALSE, 0);

- tambahkan tombol baru yang berfungsi sebagai penutup aplikasi.



gtk_box_pack_start() berfungsi untuk menempatkan widget ke dalam boks horisontal maupun vertikal dengan berurutan dari kiri ke kanan atau dari atas ke bawah. Variasi lain adalah fungsi gtk_box_pack_end(), menempatkan widget dari kanan ke kiri untuk GtkHBox dan dari bawah ke atas untuk GtkVBox.

Kemungkinan parameter pada fungsi gtk_box_pack_*() dapat dilihat pada contoh program berikut. Sebelum kompilasi, Anda dapat menerka lebih dahulu seperti apa program yang akan ditampilkan.

Contoh program boxpack.c :

#include <stdio.h>
#include <stdlib.h>
#include "gtk/gtk.h"

gint delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
gtk_main_quit ();
return FALSE;
}

/* Membuat hbox dengan tombol-tombol di dalamnya */
GtkWidget *make_box( gboolean homogeneous,
gint spacing,
gboolean expand,
gboolean fill,
guint padding )
{
GtkWidget *box;
GtkWidget *button;
char padstr[80];

/* Membuat hbox dengan parameter yang sesuai */
box = gtk_hbox_new (homogeneous, spacing);

/* Membuat beberapa tombol */
button = gtk_button_new_with_label ("gtk_box_pack");
gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
gtk_widget_show (button);

button = gtk_button_new_with_label ("(box,");
gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
gtk_widget_show (button);

button = gtk_button_new_with_label ("button,");
gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
gtk_widget_show (button);

/* Tergantung pada nilai expand, buat tombol dengan label yang sesuai */
if (expand == TRUE)
button = gtk_button_new_with_label ("TRUE,");
else
button = gtk_button_new_with_label ("FALSE,");

gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
gtk_widget_show (button);

/* Mirip dengan yang di atas, tergantung pada nilai fill */
button = gtk_button_new_with_label (fill ? "TRUE," : "FALSE,");
gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
gtk_widget_show (button);

sprintf (padstr, "%d);", padding);

button = gtk_button_new_with_label (padstr);
gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
gtk_widget_show (button);

return box;
}

int main( int argc,
char *argv[])
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *separator;
GtkWidget *label;
GtkWidget *quitbox;
int which;

/* Inisialisasi */
gtk_init (&argc, &argv);

if (argc != 2) {
fprintf (stderr, "usage: packbox num, where num is 1, 2, or 3.\n");
/* Keluar jika tidak sesuai dengan pesannya */
exit (1);
}

which = atoi (argv[1]);

/* Create our window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

/* Buatlah hal ini menjadi kebiasaan */
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);

/* Membuat vbox */
box1 = gtk_vbox_new (FALSE, 0);

/* Pilih contoh yang akan ditampilkan */
switch (which) {
case 1:
/* buat label */
label = gtk_label_new ("gtk_hbox_new (FALSE, 0);");

/* Align ke kiri */
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);

/* Letakkan ke dalam vbox */
gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);

/* Tampilkan label */
gtk_widget_show (label);

/* Panggil fungsi make_box - homogeneous = FALSE, spacing = 0,
* expand = FALSE, fill = FALSE, padding = 0 */
box2 = make_box (FALSE, 0, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

/* Panggil fungsi make_box - homogeneous = FALSE, spacing = 0,
* expand = TRUE, fill = FALSE, padding = 0 */
box2 = make_box (FALSE, 0, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

/* Panggil fungsi make_box : homogeneous, spacing, expand, fill,
* padding */
box2 = make_box (FALSE, 0, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

/* Buat separator */
separator = gtk_hseparator_new ();

/* Letakkan ke dalam box */
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
gtk_widget_show (separator);

/* Buat label lain */
label = gtk_label_new ("gtk_hbox_new (TRUE, 0);");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
gtk_widget_show (label);

/* Panggil fungsi make_box : homogeneous, spacing, expand, fill,
* padding */
box2 = make_box (TRUE, 0, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

/* Panggil fungsi make_box : homogeneous, spacing, expand, fill,
* padding */
box2 = make_box (TRUE, 0, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

/* Separator lain */
separator = gtk_hseparator_new ();
/* The last 3 arguments to gtk_box_pack_start are:
* expand, fill, padding. */
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
gtk_widget_show (separator);

break;

case 2:

label = gtk_label_new ("gtk_hbox_new (FALSE, 10);");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
gtk_widget_show (label);

box2 = make_box (FALSE, 10, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

box2 = make_box (FALSE, 10, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
gtk_widget_show (separator);

label = gtk_label_new ("gtk_hbox_new (FALSE, 0);");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
gtk_widget_show (label);

box2 = make_box (FALSE, 0, TRUE, FALSE, 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

box2 = make_box (FALSE, 0, TRUE, TRUE, 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
gtk_widget_show (separator);
break;

case 3:

/* Contoh penggunaan gtk_box_pack_end() untuk rapat ke kanan */
box2 = make_box (FALSE, 0, FALSE, FALSE, 0);

/* Label */
label = gtk_label_new ("end");
/* Menggunakan gtk_box_pack_end(), untuk meletakkan di sisi
* kanan. */
gtk_box_pack_end (GTK_BOX (box2), label, FALSE, FALSE, 0);

gtk_widget_show (label);

gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
gtk_widget_show (box2);

separator = gtk_hseparator_new ();
/* set ukuran separator menjadi lebar 400 pixel dan tinggi 5 pixel
* Hal ini juga memaksa ukuran lebar hbox menjadi 400 pixel */
gtk_widget_set_size_request (separator, 400, 5);

gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
gtk_widget_show (separator);
}


quitbox = gtk_hbox_new (FALSE, 0);


button = gtk_button_new_with_label ("Quit");


g_signal_connect_swapped (G_OBJECT (button), "clicked",
G_CALLBACK (gtk_main_quit),
G_OBJECT (window));

gtk_box_pack_start (GTK_BOX (quitbox), button, TRUE, FALSE, 0);

gtk_box_pack_start (GTK_BOX (box1), quitbox, FALSE, FALSE, 0);

gtk_container_add (GTK_CONTAINER (window), box1);


gtk_widget_show (button);
gtk_widget_show (quitbox);

gtk_widget_show (box1);

gtk_widget_show (window);


gtk_main ();


return 0;
}

Anda jalankan program (jika nama program Anda boxpack) di atas dengan cara :

$ ./boxpack 1

Atau

$ ./boxpack 2

Atau

$ ./boxpack 3

Kemudian ubahlah ukuran windownya, perhatikan ukuran dan posisi masing-masing widget.

gtk_hbox_new() mempunyai dua argumen. Argumen pertama menentukan apakah alokasi panjang (karena boks horisontal, atau tinggi jika boks vertikal) tiap widget anggota selalu sama. Namun panjang widget belum tentu sama dengan panjang alokasinya. Argumen kedua menentukan jumlah ruang (spacing) diantara widget anggota.

Fungsi untuk memasukkan widget ke dalam box,

void gtk_box_pack_start( GtkBox *box, 
GtkWidget *child,
gboolean expand,
gboolean fill,
guint padding );

Child adalah widget yang akan dimasukkan ke dalam box. Expand : TRUE, jika Anda ingin child menyebar dalam box, FALSE, jika Anda ingin child merapat ke satu sisi box.

Jika expand bernilai TRUE, nilai fill akan berpengaruh dalam mengisi ruang dalam box. Isi fill dengan TRUE jika Anda ingin ukuran child mengisi ruang kosong.

Padding adalah ruang di kiri dan kanan (GtkVBox) atau di atas dan bawah (GtkHBox) child.

<<Apa yang Telah Anda Buat Dasar-dasar Gtk+
Menggunakan Tabel>>
Hosted by www.Geocities.ws

1