Next, any program will have some user interface
elements. In the X tradition, these are called widgets. All widgets are
subclasses of the
GtkWidget base class, so you can use a GtkWidget* to refer to
them. (Since C has no native support for object
inheritance, GTK+ has its own mechanism---the chapter called The GTK+
Object and Type System describes this.)
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new();
label = gtk_label_new("Hello, World!");
gtk_container_add(GTK_CONTAINER(button), label);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_window_set_title(GTK_WINDOW(window), "Hello");
gtk_container_set_border_width(GTK_CONTAINER(button), 10);
|
Each widget has a function called gtk_widgetname_new(), analagous to a
constructor in C++ or Java. This function allocates a
new object, initializes it, and returns a pointer to
it. All of the _new()
routines return a
GtkWidget*, even though they allocate a
subclass; this is for convenience.
Once you have a
GtkWidget* representing an object, you can
manipulate the object using its methods. All GTK+
widget functions begin with the name of the type they
operate on, and accept a pointer to that type as the
first argument. In the above code, gtk_container_add() accepts a GtkContainer* as the first
argument. The macro
GTK_CONTAINER() casts the GtkWidget*, and also performs a
runtime type check. Casting is required because C
does not understand the inheritance relationship.
As you might imagine,
GtkButton and
GtkWindow are both subclasses of GtkContainer. A GtkContainer can hold any other
widget inside. The code creates a toplevel window,
places a button inside it, and places a label (line
of text) inside the button. Then it sets the window
title, and adds a small cosmetic border around the
button.