Low Level GUI Programming
To program a GUI at the GTK+ level, you need the stklos-gtk-base
package. This package is a simple wrapping of the GTK+ library in STklos.
To install the package, just issue the following command:
Before using this package, you can test that everything works with the following command:
Programming with this package is very similar to programming a GUI in C. As a consequence, standard GTK+ documentation can easily be followed to build a GUI.
Example
Once, the stklos-gtk-base
package is installed, it is easy to build the following GUI.
This interface uses two callback procedures:
hello
which is called whenever a button is pressed,delete-event
which is called when the window is closed.
The GTK+ events are managed here in a separate thread. This is particularly useful in an interactive environment where the GUI can be partially created and widgets are added once at a time.
;;;
;;; simple-gtk.stk -- A Simple example in GTK+
;;;
(require "stklos-gtk-base")
(import stklos-gtk-base)
;;;;
;;;; Callbacks
;;;;
(define (hello widget data)
(printf "Hello: ~S was pressed\n" data))
(define (delete-event widget event data)
(gtk-main-quit)
#f)
;;;;
;;;; Application
;;;;
(define window #f)
(define button #f)
(define box1 #f)
;; Initialize GTK+
(gtk-init (void) (void))
;; Window
(set! window (gtk-window-new 0))
(gtk-window-set-title window "Hello Buttons!")
(g-signal-connect window "delete_event" delete-event 1)
(gtk-container-set-border-width window 10)
;; box1
(set! box1 (gtk-hbox-new #f 0))
(gtk-container-add window box1)
;; button1
(set! button (gtk-button-new-with-label "Button 1"))
(g-signal-connect button "clicked" hello "Button 1")
(gtk-box-pack-start box1 button #t #t 0)
(gtk-widget-show button)
;; button2
(set! button (gtk-button-new-with-label "Button 2"))
(g-signal-connect button "clicked" hello "Button 2")
(gtk-box-pack-start box1 button #t #t 0)
(gtk-widget-show button)
(gtk-widget-show box1)
(gtk-widget-show window)
;; Here we go....
(let ((thr (make-thread (lambda ()
(gtk-main)
(eprintf "End of GTK+ thread\n")))))
;; thr is the GTK+ thread in charge of GTK+ event
(thread-join! (thread-start! thr))
;; GTK thread is dead; we can exit
(exit 0))
You can run this program with the followwing command (provided you have installed the stklos-gtk-base
package:
Version in C
To compare the Scheme version to classical GTK+ programming, hereafter is a possible way to program the very same interface in C.
//
// simple-gtk.c -- A Simple example in GTK+
//
#include <gtk/gtk.h>
void hello(GtkWidget *widget, gpointer data)
{
g_print ("Hello again - %s was pressed\n", (gchar *) data);
}
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
gtk_main_quit ();
return FALSE;
}
int main(int argc, char *argv[])
{
// GtkWidget is the storage type for widgets
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
// Initalize GTK+
gtk_init (&argc, &argv);
// Window
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
// box1
box1 = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
// button1
button = gtk_button_new_with_label ("Button 1");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (hello), (gpointer) "Button 1");
gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);
gtk_widget_show (button);
// button2
button = gtk_button_new_with_label ("Button 2");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (hello), (gpointer) "Button 2");
gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gtk_widget_show (box1);
gtk_widget_show (window);
gtk_main ();
printf("GTK event loop terminated\n");
return 0;
}
To run this progam, you can use for instance