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 variable STKLOS_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:

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))

Download simple-gtk.stk

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)
{
  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;
}


Download simple-gtk.c

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

Back to Screenshots