264 lines
12 KiB
XML
264 lines
12 KiB
XML
<?xml version="1.0"?>
|
||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||
]>
|
||
<chapter id="gtk-getting-started" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||
<title>Getting Started with GTK+</title>
|
||
|
||
<para>This chapter contains some tutorial information to get you
|
||
started with GTK+ programming. It assumes that you have GTK+, its
|
||
dependencies and a C compiler installed and ready to use. If you
|
||
need to build GTK+ itself first, refer to the
|
||
<link linkend="gtk-compiling">Compiling the GTK+ libraries</link>
|
||
section in this reference.</para>
|
||
|
||
<simplesect>
|
||
<title>Basics</title>
|
||
|
||
<para>To begin our introduction to GTK, we'll start with the simplest
|
||
program possible. This program will create an empty 200 × 200 pixel
|
||
window.</para>
|
||
|
||
<informalfigure>
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="window-default.png" format="PNG"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
</informalfigure>
|
||
|
||
<informalexample>
|
||
<para>Create a new file with the following content named example-0.c.</para>
|
||
<programlisting><xi:include href="../../../../examples/window-default.c" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
You can compile the program above with GCC using:
|
||
<literallayout>
|
||
<literal>gcc `pkg-config --cflags gtk+-3.0` -o example-0 example-0.c `pkg-config --libs gtk+-3.0`</literal>
|
||
</literallayout>
|
||
</para>
|
||
|
||
<note><para>For more information on how to compile a GTK+ application, please
|
||
refer to the <link linkend="gtk-compiling">Compiling GTK+ Applications</link>
|
||
section in this reference.</para></note>
|
||
|
||
<para>All GTK+ applications will, of course, include
|
||
<filename>gtk/gtk.h</filename>, which declares functions, types and
|
||
macros required by GTK+ applications.</para>
|
||
|
||
<warning><para>Even if GTK+ installs multiple header files, only the
|
||
top-level <filename>gtk/gtk.h</filename> header can be directly included
|
||
by third party code. The compiler will abort with an error if any other
|
||
header is directly included.</para></warning>
|
||
|
||
<para>We then proceed into the <function>main</function>() function of the
|
||
application, and we declare a <varname>window</varname> variable as a pointer
|
||
of type #GtkWidget.</para>
|
||
|
||
<para>The following line will call gtk_init(), which
|
||
is the initialization function for GTK+; this function will set up GTK+,
|
||
the type system, the connection to the windowing environment, etc. The
|
||
gtk_init() takes as arguments the pointers to the command line arguments
|
||
counter and string array; this allows GTK+ to parse specific command line
|
||
arguments that control the behavior of GTK+ itself. The parsed arguments
|
||
will be removed from the array, leaving the unrecognized ones for your
|
||
application to parse.</para>
|
||
|
||
<note><para>For more information on which command line arguments GTK+
|
||
recognizes, please refer to the <link linkend="gtk-running">Running GTK+
|
||
Applications</link> section in this reference.</para></note>
|
||
|
||
<para>The call to gtk_window_new() will create a new #GtkWindow and store
|
||
it inside the <varname>window</varname> variable. The type of the window
|
||
is %GTK_WINDOW_TOPLEVEL, which means that the #GtkWindow will be managed
|
||
by the windowing system: it will have a frame, a title bar and window
|
||
controls, depending on the platform.</para>
|
||
|
||
<para>In order to terminate the application when the #GtkWindow is
|
||
destroyed, we connect the #GtkWidget::destroy signal to the gtk_main_quit()
|
||
function. This function will terminate the GTK+ main loop started by calling
|
||
gtk_main() later. The #GtkWidget::destroy signal is emitted when a widget is
|
||
destroyed, either by explicitly calling gtk_widget_destroy() or when the
|
||
widget is unparented. Top-level #GtkWindow<!-- -->s are also destroyed when
|
||
the Close window control button is clicked.</para>
|
||
|
||
<para>#GtkWidget<!-- -->s are hidden by default. By calling gtk_widget_show()
|
||
on a #GtkWidget we are asking GTK+ to set the visibility attribute so that it
|
||
can be displayed. All this work is done after the main loop has been
|
||
started.</para>
|
||
|
||
<para>The last line of interest is the call to gtk_main(). This function will
|
||
start the GTK+ main loop and will block the control flow of the
|
||
main() until the gtk_main_quit() function is called.</para>
|
||
|
||
<para>While the program is running, GTK+ is receiving
|
||
<firstterm>events</firstterm>. These are typically input events caused by
|
||
the user interacting with your program, but also things like messages from
|
||
the window manager or other applications. GTK+ processes these and as a
|
||
result, <firstterm>signals</firstterm> may be emitted on your widgets.
|
||
Connecting handlers for these signals is how you normally make your
|
||
program do something in response to user input.</para>
|
||
|
||
<para>The following example is slightly more complex, and tries to
|
||
showcase some of the capabilities of GTK+.</para>
|
||
|
||
<para>In the long tradition of programming languages and libraries,
|
||
it is called <emphasis>Hello, World</emphasis>.</para>
|
||
|
||
<informalfigure>
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="hello-world.png" format="PNG"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
</informalfigure>
|
||
|
||
<example id="gtk-getting-started-hello-world">
|
||
<title>Hello World in GTK+</title>
|
||
<para>Create a new file with the following content named example-1.c.</para>
|
||
<programlisting><xi:include href="../../../../examples/hello-world.c" parse="text">
|
||
<xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
You can compile the program above with GCC using:
|
||
<literallayout>
|
||
<literal>gcc `pkg-config --cflags gtk+-3.0` -o example-1 example-1.c `pkg-config --libs gtk+-3.0`</literal>
|
||
</literallayout>
|
||
</para>
|
||
</simplesect>
|
||
|
||
<simplesect>
|
||
<title>Packing</title>
|
||
|
||
<para>When creating an application, you'll want to put more than one widget
|
||
inside a window. Our first helloworld example only used one widget so we
|
||
could simply use a gtk_container_add() call to "pack" the widget into the
|
||
window. But when you want to put more than one widget into a window, it
|
||
it becomes important to control how each widget is positioned and sized.
|
||
This is where packing comes in.</para>
|
||
|
||
<para>GTK+ comes with a large variety of <firstterm>layout containers</firstterm>
|
||
whose purpose it is to control the layout of the child widgets that are
|
||
added to them. See <xref linkend="LayoutContainers"/> for an overview.</para>
|
||
|
||
<para>The following example shows how the GtkGrid container lets you
|
||
arrange several buttons:</para>
|
||
|
||
<informalfigure>
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="grid-packing.png" format="PNG"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
</informalfigure>
|
||
|
||
<example id="gtk-getting-started-grid-packing">
|
||
<title>Packing buttons</title>
|
||
<para>Create a new file with the following content named example-2.c.</para>
|
||
<programlisting><xi:include href="../../../../examples/grid-packing.c" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||
</example>
|
||
<para>
|
||
You can compile the program above with GCC using:
|
||
<literallayout>
|
||
<literal>gcc `pkg-config --cflags gtk+-3.0` -o example-2 example-2.c `pkg-config --libs gtk+-3.0`</literal>
|
||
</literallayout>
|
||
</para>
|
||
</simplesect>
|
||
|
||
<simplesect>
|
||
<title>Drawing</title>
|
||
|
||
<para>Many widgets, like buttons, do all their drawing themselves. You
|
||
just tell them the label you want to see, and they figure out what font
|
||
to use, draw the button outline and focus rectangle, etc. Sometimes, it
|
||
is necessary to do some custom drawing. In that case, a #GtkDrawingArea
|
||
might be the right widget to use. It offers a canvas on which you can
|
||
draw by connecting to the #GtkWidget::draw signal.
|
||
</para>
|
||
|
||
<para>The contents of a widget often need to be partially or fully redrawn,
|
||
e.g. when another window is moved and uncovers part of the widget, or
|
||
when tie window containing it is resized. It is also possible to explicitly
|
||
cause part or all of the widget to be redrawn, by calling
|
||
gtk_widget_queue_draw() or its variants. GTK+ takes care of most of the
|
||
details by providing a ready-to-use cairo context to the ::draw signal
|
||
handler.</para>
|
||
|
||
<para>The following example shows a ::draw signal handler. It is a bit
|
||
more complicated than the previous examples, since it also demonstrates
|
||
input event handling by means of ::button-press and ::motion-notify
|
||
handlers.</para>
|
||
|
||
<informalfigure>
|
||
<mediaobject>
|
||
<imageobject>
|
||
<imagedata fileref="drawing.png" format="PNG"/>
|
||
</imageobject>
|
||
</mediaobject>
|
||
</informalfigure>
|
||
|
||
<example id="gtk-getting-started-drawing">
|
||
<title>Drawing in response to input</title>
|
||
<para>Create a new file with the following content named example-3.c.</para>
|
||
<programlisting><xi:include href="../../../../examples/drawing.c" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||
</example>
|
||
<para>
|
||
You can compile the program above with GCC using:
|
||
<literallayout>
|
||
<literal>gcc `pkg-config --cflags gtk+-3.0` -o example-3 example-3.c `pkg-config --libs gtk+-3.0`</literal>
|
||
</literallayout>
|
||
</para>
|
||
</simplesect>
|
||
|
||
<simplesect>
|
||
<title>Building interfaces</title>
|
||
|
||
<para>When construcing a more complicated user interface, with dozens
|
||
or hundreds of widgets, doing all the setup work in C code is
|
||
cumbersome, and making changes becomes next to impossible.</para>
|
||
|
||
<para>Thankfully, GTK+ supports the separation of user interface
|
||
layout from your business logic, by using UI descriptions in an
|
||
XML format that can be parsed by the #GtkBuilder class.</para>
|
||
|
||
<example>
|
||
<title>Packing buttons with GtkBuilder</title>
|
||
<para>Create a new file with the following content named example-4.c.</para>
|
||
<programlisting><xi:include href="../../../../examples/builder.c" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||
<para>Create a new file with the following content named builder.ui.</para>
|
||
<programlisting><xi:include href="../../../../examples/builder.ui" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||
</example>
|
||
<para>
|
||
You can compile the program above with GCC using:
|
||
<literallayout>
|
||
<literal>gcc `pkg-config --cflags gtk+-3.0` -o example-4 example-4.c `pkg-config --libs gtk+-3.0`</literal>
|
||
</literallayout>
|
||
</para>
|
||
|
||
<para>Note that GtkBuilder can also be used to construct objects
|
||
that are not widgets, such as tree models, adjustments, etc.
|
||
That is the reason the method we use here is called
|
||
gtk_builder_get_object() and returns a GObject* instead of a
|
||
GtkWidget*.</para>
|
||
|
||
<para>Normally, you would pass a full path to
|
||
gtk_builder_add_from_file() to make the execution of your program
|
||
independent of the current directory. A common location to install
|
||
UI descriptions and similar data is
|
||
<filename>/usr/share/<replaceable>appname</replaceable></filename>.
|
||
</para>
|
||
|
||
<para>It is also possible to embed the UI description in the source
|
||
code as a string and use gtk_builder_add_from_string() to load it.
|
||
But keeping the UI description in a separate file has several
|
||
advantages: It is then possible to make minor adjustments to the UI
|
||
without recompiling your program, and, more importantly, graphical
|
||
UI editors such as <ulink url="http://glade.gnome.org">glade</ulink>
|
||
can load the file and allow you to create and modify your UI by
|
||
point-and-click.</para>
|
||
|
||
</simplesect>
|
||
</chapter>
|