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:
$ stklos-pkg --install stklos-gtk-base
- Note:
- The package
stklos-gtk-base
searches the system GUI toolkit libraries in some standard places (mainly/usr/lib
and/usr/local/lib
). If your libraries are installed in another directory, you can set the shell variableSTKLOS_GTK_DIR
to that directory name. This variable is used both for installing the ScmPkg and for running your program.
Before using this package, you can test that everything works with the following command:
$ stklos-pkg --test stklos-gtk-base
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+
;;;
"stklos-gtk-base")
(require
(import stklos-gtk-base)
;;;;
;;;; Callbacks
;;;;
define (hello widget data)
("Hello: ~S was pressed\n" data))
(printf
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))
("Hello Buttons!")
(gtk-window-set-title window "delete_event" delete-event 1)
(g-signal-connect window 10)
(gtk-container-set-border-width window
;; box1
set! box1 (gtk-hbox-new #f 0))
(
(gtk-container-add window box1)
;; button1
set! button (gtk-button-new-with-label "Button 1"))
("clicked" hello "Button 1")
(g-signal-connect button #t #t 0)
(gtk-box-pack-start box1 button
(gtk-widget-show button)
;; button2
set! button (gtk-button-new-with-label "Button 2"))
("clicked" hello "Button 2")
(g-signal-connect button #t #t 0)
(gtk-box-pack-start box1 button
(gtk-widget-show button)
(gtk-widget-show box1)
(gtk-widget-show window)
;; Here we go....
let ((thr (make-thread (lambda ()
(
(gtk-main)"End of GTK+ thread\n")))))
(eprintf ;; thr is the GTK+ thread in charge of GTK+ event
(thread-join! (thread-start! thr));; GTK thread is dead; we can exit
0)) (exit
You can run this program with the followwing command (provided you have installed the stklos-gtk-base
package:
$ stklos -f simple-gtk.stk
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)
{
("Hello again - %s was pressed\n", (gchar *) data);
g_print }
(GtkWidget *widget, GdkEvent *event, gpointer data)
gint delete_event{
();
gtk_main_quit return FALSE;
}
int main(int argc, char *argv[])
{
// GtkWidget is the storage type for widgets
*window;
GtkWidget *button;
GtkWidget *box1;
GtkWidget
// Initalize GTK+
(&argc, &argv);
gtk_init
// Window
= gtk_window_new (GTK_WINDOW_TOPLEVEL);
window (GTK_WINDOW (window), "Hello Buttons!");
gtk_window_set_title (G_OBJECT (window), "delete_event",
g_signal_connect (delete_event), NULL);
G_CALLBACK (GTK_CONTAINER (window), 10);
gtk_container_set_border_width
// box1
= gtk_hbox_new (FALSE, 0);
box1 (GTK_CONTAINER (window), box1);
gtk_container_add
// button1
= gtk_button_new_with_label ("Button 1");
button (G_OBJECT (button), "clicked",
g_signal_connect (hello), (gpointer) "Button 1");
G_CALLBACK (GTK_BOX(box1), button, TRUE, TRUE, 0);
gtk_box_pack_start (button);
gtk_widget_show
// button2
= gtk_button_new_with_label ("Button 2");
button (G_OBJECT (button), "clicked",
g_signal_connect (hello), (gpointer) "Button 2");
G_CALLBACK (GTK_BOX (box1), button, TRUE, TRUE, 0);
gtk_box_pack_start(button);
gtk_widget_show
(box1);
gtk_widget_show (window);
gtk_widget_show
();
gtk_main ("GTK event loop terminated\n");
printfreturn 0;
}
To run this progam, you can use for instance
$ gcc -o simple-gtk simple-gtk.c $(pkg-config gtk+-2.0 --cflags --libs)
$ ./simple-gtk