How to Write a Basic Gtk# Program with Mono

Editor's note: O'Reilly's upcoming Mono: A Developer's Notebook walks you through nearly 50 mini-projects that will introduce you to the most important and compelling aspects of the 1.0 release. This article, which shows you how to install Mono on Windows, how Gtk# works, and how to write a simple Gtk# program, is just the sort of mini-project you'll find in the book.

Gtk# is the Mono API for the GTK+ user interface toolkit.
While Mono implements Windows.Forms, Gtk# is a
completely open source alternative, and the look-andfeel
of choice for Mono programs running on Linux. This
lab demonstrates how to install Mono on Windows and
write a simple Gtk# program.

Mono is an open
source implementation
of the
Common Language
Runtime. It
includes the Gtk#
user interface
libraries.

Any user interface programming toolkit defines a way
for delivering events from the user to the program.
Whereas with non-interactive programs the flow of
control is under the programmer's direction, interactive
programs must respond to the events they receive.

In Gtk#, the flow of control is governed by the main
event loop. The program yields its control to the main
loop, which is responsible for processing input events.
Whenever events that the program is interested in
happen, handlers for those events are called and control
given to the main program.

Now set up the MONO_PATH environmental variable to
refer to the bin subdirectory of your Mono installation,
for example C:\Program Files\Mono-0.31\bin. Ensure
your PATH variable also includes this directory.
Now that Mono is happily installed, on with the lab.
We will construct a basic Gtk# program using a window
and a button. Both of these raise events, and need
add handlers for those that the programmer wants to
process. Example 2 shows the program listing.

The -r:gtk-sharp
option to the
compiler causes it
to reference the
Gtk# assembly.
Without it, the
compiler wouldn't
know where to
find the Gtk
classes.

Use a regular text editor to save the source in Main.cs
and compile it like this:

$ mcs Main.cs -pkg:gtk-sharp
$ mono Main.exe

When you run the application, you will see a window
as in Figure 8: the button takes up the entire space in
the window. Click the button a few times, and you'll
see the output on the terminal as shown in Figure 9.

Figure 8. Gtk# window with a button

Figure 9. Terminal output

How does it work?

The Gtk namespace is imported with using Gtk. The
basic Gtk# tasks of initialising the toolkit are performed
by the Application class. Specifically, there are
three static methods of interest.

If you want your
application to
check whether it
can use graphics,
use the InitCheck
method instead of
Init. That way it
won't fail horribly
and you can fall
back to a text
interface.

Init causes the Gtk# library to be initialized. You
won't get very far without doing this.

Run causes the flow of control to enter the main
event loop.

Quit causes the event loop to terminate when
control is returned to it.

The creation of the window and its button is a trivial
matter: there are more interesting examples in the
other labs. What is more relevant here is the hooking up of the event handlers. Every widget (user interface
element) in Gtk# is capable of raising a variety of
events. Many of these are derived from the basic
Widget class, from which all the Gtk# widgets inherit.
Typical events include Focused, sent when the widget
receives user focus, and DeleteEvent, sent when the
widget is deleted.

The event
handlers need not
be static methods
if they need to
access an object
instance. The only
difference is to
assign them
prefixed by the
instance.

When an event is raised, the assigned handlers are
invoked. Events can have any number of handlers
assigned. Example 2 shows the handler Window_Delete being added for the event DeleteEvent.

Our Window_Delete handler does two things of interest.
First, it instructs the main loop to exit when control
is returned to it. Secondly, it sends true back as a
return value via the args object. This stops any subsequent
handlers getting the event.

The handler for the Button is much the same, and is
more typical of the general widget event handler. Buttons
have some specialized events, of which Clicked is
the most useful.

The assignment of the handlers has been shown in full
to give some hint as to the underlying implementation.
However, it's possible to take a shortcut and write the two
lines as follows:

w.DeleteEvent += Window_Delete;
b.Clicked += Button_Clicked;

What about...

An introduction to programming with Gtk# can be
found as part of the documenation shipped with Monodoc.
Refer to the Mono for Gnome Applications section
of the Mono Handbook, available from the
Monodoc table of contents. As ever, another excellent
source of reference material is the Gtk# API reference
itself in Monodoc. You can either install Monodoc from
http://go-mono.com/download.html or read its contents
online at http://go-mono.com:8080/.

To understand more about delegates and events, refer
to Chapter 2 of C# Essentials, 2nd Edition by Ben Albahari,
Peter Drayton, and Brad Merrill (O'Reilly, 2002).
A good introduction to the GTK+ toolkit can be found in
the GTK+ 2.0 Tutorial, available at http://www.gtk.org/
tutorial/. Although specific to the C language implementation
of GTK+, the tutorial contains a lot of theory
about the toolkit that we will only gloss over in this
book.