GTK+ ohjelmointi Juha Järvensivu 2007
Yleistä GTK+ eli Gimp Toolkit Erityisesti unix-puolella käytetty C-kielinen kirjasto graafisten käyttöliittymien ohjelmointiin LGPL-lisenssi Olennainen osa GNOMEtyöpöytäympäristöä
Gtk+:n tärkeimmät komponentit Gtk+ Sisältää Graafiset widgetit GLib Omat tyypitykset (guint, gpointer ) Oliopohjaisuuden perusta (GObject) Tapahtumasilmukan käyttöön tarvittavat rajapinnat Kirjastofunktioita Alustariippumattomuus Pango Fonttien piirto ja asettelu Tuki monikielisyydelle ATK Käytettävyysrajapinnat Erikoiset syöttölaitteet
GDK GIMP Drawing Kit Grafiikkakirjasto, joka sisältää matalan tason piirtofunktiot (wrapperi XLib kirjastolle) Sijaitsee X-ikkunointi järjestelmän ja GTK+:n välissä XLib = rajapinta X-ikkunointi järjestelmään
GTK-lohkokaavio GTK+ Pango ATK GDK GLib X11 Operating System
UI-designereita Glade http://glade.gnome.org/ xml-formaatti Libglade library Gazpacho Python kielellä toteutettu GUI-builder
GTK-sovelluksen toiminta 1. Alustetaan GTK 2. Luodaan UI-komponentit (Widgetit) 3. Liitetään tarvittavat tapahtumakäsittelijät widgetteihin 4. Luodaan ikkunan layout pakkaamalla widgetit säiliöihin 5. Näytetään widgetit 6. Käynnistetään sanomasilmukka 7. Kuunnellaan tapahtumia 8. Lopetetaan sovellus ja tehdään tarvittavat siivoustoimet
Widgetit ja containerit
GTK+ widgetit Käyttöliittymä elementti (esim Button) Osa widgeteistä ikkunattomia Ei yhteyttä ikkunointi järjestelmään Piirretään parentin sisään Ei oletuksena mahdollista kuunnella eventtejä Esim Label
EventBox Kytkee ikkunattomat widgetit X-Window ikkunointijärjestelmään GtkWidget *event_box; GtkWidget *label; event_box = gtk_event_box_new (); gtk_container_add (GTK_CONTAINER (window), event_box); gtk_widget_show (event_box); gtk_container_add (GTK_CONTAINER (event_box), label); gtk_widget_show (label);
Containers gtk_container_add (GTK_CONTAINER (window), box1); Ikkunaan voidaan liittää yksi UI-komponentti Käyttöliittymäikkunan luonti tapahtuu lisäämällä tarvittavat UI-komponentit pakkauslaatikoihin HBox VBox Sisäkkäiset pakkaukset joustava keino määritellä käyttöliittymän layout (asemointi)
Containers Etuja Tarjoaa joustavan tavan määritellä käyttöliittymiä (sisäkkäiset pakkaukset) Käyttöliittymän automaatinen skaalautuvuus Haittoja Monimutkaisissa dialogeissa containereiden määrä kasvaa suureksi, joka hankaloittaa käyttöliittymän ylläpidettävyyttä ja monimutkaistaa lähdekoodia Avuksi graafiset UI designerit, kuten Glade ja Gazpacho
Containers GtkHBox gtk_hbox_new(homogenous, padding); GtkVBox gtk_vbox_new(homogenous, padding); GtkTable gtk_table_new(rows, colors, homogenous);
Containers Homogenous Kertoo ovatko objektit saman kokoisia Padding Objektien välinen etäisyys
Objektin lisääminen containeriin void gtk_box_pack_start( GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding );
Objektin lisääminen containeriin box = gtk_hbox_new (homogeneous, spacing); button = gtk_button_new_with_label ( label"); // Lisätään komponentti vasempaan reunaan gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding); gtk_widget_show (button); button = gtk_button_new_with_label ( label2"); // Lisätään komponentti oikeaan reunaan gtk_box_pack_end (GTK_BOX (box), button, expand, fill, padding); gtk_widget_show (button);
Tyyppimuunnokset G_OBJECT (object) GTK_WIDGET (widget) GTK_OBJECT (object) GTK_SIGNAL_FUNC (function) GTK_CONTAINER (container) GTK_WINDOW (window) GTK_BOX (box)
Widget attributes void gtk_widget_activate( GtkWidget *widget ); void gtk_widget_set_name( GtkWidget *widget, gchar *name ); gchar *gtk_widget_get_name( GtkWidget *widget ); void gtk_widget_set_size_request( GtkWidget *widget, gint width, gint height ); void gtk_widget_show( GtkWidget *widget ); void gtk_widget_hide( GtkWidget *widget );
Signaalit ja callback funktiot
Signaalin prototyyppi gulong g_signal_connect( gpointer *object, const gchar *name, GCallback func, gpointer func_data );
Esimerkki g_signal_connect ( G_OBJECT (button), clicked", G_CALLBACK (hello), NULL );
Callback-funktio prototyyppi void callback_func( GtkWidget *widget,... /* other signal arguments */ gpointer callback_data );
Esimerkki static void hello( GtkWidget *widget, gpointer data ) { g_print ("Hello World\n"); }
Disconnect signal gulong g_signal_connect( GObject *object, const gchar *name, GCallback func, gpointer func_data ); void g_signal_handler_disconnect( GObject *object, gulong handler_id );
Eventtejä event button_press_event button_release_event scroll_event motion_notify_event delete_event destroy_event expose_event key_press_event key_release_event enter_notify_event leave_notify_event configure_event focus_in_event focus_out_event map_event unmap_event property_notify_event selection_clear_event selection_request_event selection_notify_event proximity_in_event proximity_out_event visibility_notify_event client_event no_expose_event window_state_event
Prototyyppi gint callback_func( GtkWidget *widget, GdkEvent *event, gpointer callback_data );
Eventin kytkeminen g_signal_connect ( G_OBJECT (button), "button_press_event", G_CALLBACK (button_press_callback), NULL);
Event-käsittelijä static gboolean button_press_callback( GtkWidget *widget, GdkEventButton *event, gpointer data ) { }
Esim: Button signals pressed Kutsutaan kun painike painetaan pohjaan released Kutsutaan kun painike vapautetaan clicked Kutsutaan kun painiketta klikataan (pressed + released) enter Kutsutaan kun kursori siirtyy painikeen kohdalle leave Kutsutaan kun kurosri poistuu painikkeen kohdalta
Esimerkki
Ikkunan luominen GTKympäristössä #include <gtk/gtk.h> int main( int argc, char *argv[] ) { GtkWidget *window; // Alustus funktio, jota kutsutaan GTK-sovelluksen käynnistyessä gtk_init (&argc, &argv); // Luodaan ikkuna-olio window = gtk_window_new (GTK_WINDOW_TOPLEVEL); // Tähän ikkunan alustustoimenpiteet // // Piirretään ikkuna ruudulle gtk_widget_show (window); // Käynnistetään GTK:n sanomasilmukka gtk_main (); // Suljetaan sovellus return 0; }
Widgetin lisääminen ikkunaan #include <gtk/gtk.h> int main( int argc, char *argv[] ) { GtkWidget *window; GtkWidget *button; // Asetetaan reunuksen leveys gtk_container_set_border_width (GTK_CONTAINER (window), 10); // Luodaan painike komponentti button = gtk_button_new_with_label ("Hello World"); // Lisätään painike ikkunaan gtk_container_add (GTK_CONTAINER (window), button); // Piirretään painike ikkunaan gtk_widget_show (button); gtk_widget_show (window); }
Sanomakäsittelijän liittäminen widgettiin #include <gtk/gtk.h> int main( int argc, char *argv[] ) { GtkWidget *button; } g_signal_connect (G_OBJECT (button), clicked", G_CALLBACK (hello), NULL); static void hello( GtkWidget *widget, gpointer data ) { g_print ("Hello World\n"); }
Menu luonti (manuaalinen) // Containeri file-valikko itemeille GtkWidget *file_menu; // file menun valikko-itemi GtkWidget *quit_item; // Create menu and menuitem file_menu = gtk_menu_new (); quit_item = gtk_menu_item_new_with_label ("Quit"); // Add menu item to menu gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), quit_item); // Connect event handler g_signal_connect_swapped (G_OBJECT (quit_item), "activate", G_CALLBACK (destroy), (gpointer) "file.quit"); // Show menu item gtk_widget_show (quit_item); // Event handler for quit menu item static void destroy( GtkWidget *widget, gpointer data ) { gtk_main_quit(); }
Menun liittäminen ikkunaan GtkWidget *menu_bar; // File-menun sisältämä itemi GtkWidget *file_item; // Luodaan menu_bar objekti menu_bar = gtk_menu_bar_new (); // Liitetään menu ikkunaan gtk_container_add (GTK_CONTAINER (window),menu_bar); // Näytetään menu gtk_widget_show (menu_bar); // Luodaan ja näytetään file menun sisältämä itemi file_item = gtk_menu_item_new_with_label ("File"); gtk_widget_show (file_item); // Liitetään file_menu file_itemiin gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item), file_menu); // Liitetään file_item menubariin gtk_menu_bar_append (GTK_MENU_BAR (menu_bar), file_item);
Lähteitä http://www.gtk.org/ http://www.gtk.org/tutorial http://www.gtk.org/api http://glade.gnome.org/ http://gazpacho.sicem.biz