858 lines
34 KiB
HTML
858 lines
34 KiB
HTML
<!--startcut ==============================================-->
|
|
<!-- *** BEGIN HTML header *** -->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<HTML><HEAD>
|
|
<title>GNOME Programming in Linux using GTK+ LG #70</title>
|
|
</HEAD>
|
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
|
|
ALINK="#FF0000">
|
|
<!-- *** END HTML header *** -->
|
|
|
|
<CENTER>
|
|
<A HREF="http://www.linuxgazette.com/">
|
|
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png"
|
|
WIDTH="600" HEIGHT="124" border="0"></A>
|
|
<BR>
|
|
|
|
<!-- *** BEGIN navbar *** -->
|
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="ghosh.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue70/ghosh2.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="mcgucken.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
|
<!-- *** END navbar *** -->
|
|
<P>
|
|
</CENTER>
|
|
|
|
<!--endcut ============================================================-->
|
|
|
|
<H4 ALIGN="center">
|
|
"Linux Gazette...<I>making Linux just a little more fun!</I>"
|
|
</H4>
|
|
|
|
<P> <HR> <P>
|
|
<!--===================================================================-->
|
|
|
|
<center>
|
|
<H1><font color="maroon">GNOME Programming in Linux using GTK+</font></H1>
|
|
<H4>By <a href="mailto:subhasish_ghosh@linuxmail.org">Subhasish Ghosh</a></H4>
|
|
</center>
|
|
<P> <HR> <P>
|
|
|
|
<!-- END header -->
|
|
|
|
|
|
|
|
|
|
<p>This article provides us with an overview of
|
|
GNOME Programming in Linux using GTK+ Toolkit. Please note: It is
|
|
assumed that the reader knows the basics of getting around in
|
|
Linux, knows how to use the GNOME environment, and possesses the
|
|
required level of C and/or C++ programming experience.</p>
|
|
|
|
<p>The code samples that have been provided along
|
|
with the text, have been checked on a computer system with the
|
|
following configuration: Compaq Presario 4010 Series computer
|
|
system, 15.5 GB Hard Disk Space, 96 MB RAM, 400 MHz Intel Celeron
|
|
Processor, Red Hat Linux 7.1 Distribution Release underlying
|
|
kernel: 2.4.2-2</p>
|
|
|
|
<p>This article has been divided into the following
|
|
sections for easy understanding of the subject matter:</p>
|
|
|
|
<p>1. <a
|
|
href="#What is GNOME all about? An Introduction.">What is GNOME
|
|
all about? An Introduction</a>.<br>
|
|
2. <a href="#The GNOME Architecture">The GNOME Architecture.</a><br>
|
|
3. <a href="#GTK+ - An Introduction">GTK+ - An Introduction</a><br>
|
|
4. <a href="#A basic program">A basic program.</a><br>
|
|
5. <a href="#Signals & Callbacks">Signals & Callbacks</a><br>
|
|
6. <a href="#Containers">Containers</a><br>
|
|
7. <a href="#Buttons">Buttons</a><br>
|
|
8. <a href="#Entry Widgets">Entry Widgets</a><br>
|
|
9. <a href="#List boxes and Combo boxes">List boxes & Combo
|
|
boxes</a><br>
|
|
10. <a href="#Menus & Toolbars">Menus & Toolbars</a><br>
|
|
11. <a href="#Dialog boxes">Dialog boxes</a><br>
|
|
12. <a href="#Conclusion & Links for Further study">Conclusion
|
|
& Links for Further study</a></p>
|
|
|
|
<p><font size="5"><strong>1. </strong></font><a
|
|
name="What is GNOME all about? An Introduction."><font size="5"><strong>What
|
|
is GNOME all about? An Introduction.</strong></font></a></p>
|
|
|
|
<p>Before entering into the exciting world of Gnome
|
|
programming in Linux, let's try to understand what Gnome actually
|
|
refers to. GNOME is the acronym for "<strong>GNU's Not Unix
|
|
Network Object Model Environment</strong>". Though it sounds
|
|
a bit complicated, Gnome is a software project with a simple aim:
|
|
To provide all Linux users with an extremely user-friendly, yet a
|
|
powerful and complete programming Desktop environment. GNOME is
|
|
currently the default Desktop system installed with the latest
|
|
releases of Red Hat and Debian Distribution releases of Linux. </p>
|
|
|
|
<p>For more specific info on GNOME and it's various
|
|
wonderful features, make sure you check out the GNOME Project
|
|
home page at <a href="http://www.gnome.org">http://www.gnome.org</a>
|
|
which provide readers with a wealth of information on GNOME,
|
|
including online documentation, news; and one could also download
|
|
the binaries and source code of GNOME compatible with most Linux
|
|
systems.</p>
|
|
|
|
<p>Now let's look at GNOME from both a
|
|
"Linux programmer's" as well as a "Linux System
|
|
Administrator's" point of view. The basic question that
|
|
comes to mind is: do they think and feel the same when they talk
|
|
about GNOME? The answer to this question is not so easy to
|
|
answer. Most Linux system administrators currently are/or have
|
|
been Linux programmers in the past or so, which makes it quite
|
|
difficult to answer this question. For an average Linux system
|
|
administrator, the GNOME environment provides a wealth of tools
|
|
that makes his/her administrative job so simple. Meanwhile, the
|
|
the GNOME programmer has a responsibility to continue
|
|
providing these facilities by designing even better programs. So,
|
|
they are in perfect harmony with each other as far as their
|
|
respective works are concerned.</p>
|
|
|
|
<p>Now let's take a bit closer look at Gnome's
|
|
functionality. GNOME is actually a programming layer that is
|
|
placed in between the X Window System (or X) and the Window
|
|
Manager software. Thus, as mentioned earlier, it provides Linux
|
|
GUI programmers with an enormous functionality that they can then
|
|
harness to design Linux based programs. But most significant of
|
|
all, the reason why GNOME is nearly indispensable for all
|
|
Linux/Unix developers is because GNOME provides these
|
|
developers/programmers with an Integrated Framework which was
|
|
specifically designed for building open-source applications with
|
|
a consistent graphical user interface.</p>
|
|
|
|
<p>The GNOME Project started in August, 1997. Some
|
|
of the initial founders included, amongst others, Peter Mattis,
|
|
Spencer Kimball, Richard Stallman, and Erik Troan and Mark Ewing
|
|
of Red Hat, Inc.</p>
|
|
|
|
|
|
<p><font size="5"><strong>2. </strong></font><a
|
|
name="The GNOME Architecture"><font size="5"><strong>The GNOME
|
|
Architecture</strong></font></a></p>
|
|
|
|
<p>
|
|
GNOME's extremely powerful, yet flexible architecture is what
|
|
provides GNOME its terrific functionality. The
|
|
base toolkit in GNOME is named <strong>GTK+</strong>(the GIMP
|
|
toolkit). It was originally written for using in <strong>GIMP</strong>(GNU
|
|
Image Manipulation Program). The proper understanding of GTK+ is
|
|
extremely necessary for the understanding of GNOME Programming. <strong>GTK+
|
|
is an object-oriented, cross-platform language-neutral toolkit
|
|
that is primarily used for creating applications independently of
|
|
GNOME</strong>. Then the question that comes up is: Then why was
|
|
GTK+ chosen as the toolkit for GNOME? The answer is simple: It
|
|
was for its support for many programming languages including C,
|
|
C++, PERL, Python, ADA etc. But it is helpful to keep in mind
|
|
always that both GNOME as well as GTK+ was written using C; so we
|
|
would be dealing here with C only.</p>
|
|
|
|
<p>Another question that should come up in the
|
|
reader's mind is: Hey, what do these things called
|
|
"Toolkits" contain? Toolkits like GTK+, Qt (the KDE
|
|
Environment is based on Qt) are collections of widgets. Which
|
|
brings us to the question: What are "Widgets"?</p>
|
|
|
|
<p><strong>Widgets</strong> are GUI objects like
|
|
buttons, menus, dialog boxes and other such objects or
|
|
object-related general functions. This can be compared with
|
|
Active Template Library (ATL 3.0) on the Microsoft Platform, which
|
|
provides Component Object Model (COM) developers with a ready-made
|
|
framework for creating COM Objects and Components (ActiveX EXEs
|
|
& ActiveX DLLs).</p>
|
|
|
|
<p><font size="5"><strong>3. </strong></font><a
|
|
name="GTK+ - An Introduction"><font size="5"><strong>GTK+ - An
|
|
Introduction</strong></font></a></p>
|
|
|
|
<p>Now let's take a closer look into some of the
|
|
features of GTK+:</p>
|
|
|
|
<ol>
|
|
<li><p>The set of libraries used by GTK+:
|
|
GLIB (GIMP Library) and GDK (GIMP Drawing Toolkit).</p>
|
|
</li>
|
|
<li><p>GLIB defines data types and provides
|
|
functions that deal with error handling and memory
|
|
routines.</p>
|
|
</li>
|
|
<li><p>GDK is the platform dependent layer that
|
|
is present in between the native graphics API and GTK+.</p>
|
|
</li>
|
|
<li><p>That's not all. GNOME adds further
|
|
functionality to GTK+ by adding a separate layer of GNOME
|
|
specific widgets and libraries.</p>
|
|
</li>
|
|
<li><p>Thus, GNOME comes with a full-featured,
|
|
object-oriented extensive widget set enabled
|
|
architecture.</p>
|
|
</li>
|
|
<li><p>Other than functionality of GTK+, we also
|
|
have the added benefits of a Custom implementation of the
|
|
CORBA system called ORBit in GNOME architecture, allowing
|
|
software objects to communicate easily and effectively.</p>
|
|
</li>
|
|
<li><p>GLIB defines its own set of basic data
|
|
types. Most of these are equivalent to the standard C
|
|
data types.</p>
|
|
</li>
|
|
</ol>
|
|
<div align="center"><center>
|
|
|
|
<table border="3" cellpadding="4" cellspacing="4">
|
|
<tr>
|
|
<td>GLIB data type</td>
|
|
<td>C language type</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">gchar</td>
|
|
<td align="center" bgcolor="#00FFFF">char</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">gshort</td>
|
|
<td align="center" bgcolor="#00FFFF">short</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">glong</td>
|
|
<td align="center" bgcolor="#00FFFF">long</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">gint</td>
|
|
<td align="center" bgcolor="#00FFFF">int</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">gboolean</td>
|
|
<td align="center" bgcolor="#00FFFF">boolean</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">gpointer</td>
|
|
<td align="center" bgcolor="#00FFFF">void*</td>
|
|
</tr>
|
|
</table>
|
|
</center></div>
|
|
|
|
<p>8. A vital requirement for proper understanding
|
|
of GTK+ is the concept of "Widget Hierarchy". Widgets
|
|
in GTK+ belong to a hierarchy so that functions that are common
|
|
to a set of widgets need only be implemented once. </p>
|
|
|
|
<p>For example, the function gtk_widget_show. This
|
|
leads to removal of duplicate code, thus leading to better and
|
|
faster program development. New widgets are derived from existing higher-level
|
|
widgets so that only the unique features of this widget are to be
|
|
written by the programmer. For example, let's look closely at
|
|
this particular widget hierarchy: </p>
|
|
|
|
<p>GtkObject --> GtkWidget --> GtkContainer
|
|
--> GtkBin --> GtkWindow --> GnomeApp</p>
|
|
|
|
<p>Thus, if you look carefully, you can see that
|
|
GnomeApp widget is derived from the higher-level GtkWindow, which
|
|
itself has been derived from the higher-level GtkBin and so on.
|
|
If we take into the consideration the essential features of the
|
|
C++ programming language, well, this reminds us of the concept of
|
|
"Inheritance". Doesn't it? Well, surely it does. And it
|
|
is this feature of the "Widget Hierarchy" that
|
|
incorporates the derived functionality in GTK+.</p>
|
|
|
|
<p>Let's now take a brief look at the widget
|
|
creation functions. For these functions to operate correctly, one
|
|
must make sure that all the GNOME and GTK+ libraries are
|
|
correctly installed. Another important thing to be kept in mind
|
|
is that the library's path must be correctly set before trying to
|
|
compile any code.</p>
|
|
|
|
<p>Let's first consider the widget creation
|
|
function, gnome_app_new(). This function as shown returns a
|
|
GtkWidget pointer, which is the generic widget. This maybe shown
|
|
as:</p>
|
|
|
|
<p>GtkWidget *ghosh;<br>
|
|
ghosh = gnome_app_new(………);</p>
|
|
|
|
<p>Please note that this also means that if we want
|
|
to call a GnomeApp specific function such as gnome_app_set_menus(),
|
|
then we have to use a macro to perform the cast from a
|
|
GtkWidget type to a GnomeApp type; which is only possible because
|
|
GnomeApp is derived from GtkWidget (see hierarchy above).</p>
|
|
|
|
<p><font size="5"><strong>4. </strong></font><a
|
|
name="A basic program"><font size="5"><strong>A basic program</strong></font></a></p>
|
|
|
|
<p>The best way to learn Linux programming is to
|
|
understand the internal workings of the kernel and by doing
|
|
programming yourself. So, let's now look at a small program to
|
|
understand the subject matter better.</p>
|
|
|
|
<p>Boot your system in Linux, and if you are in the
|
|
CLI (command line interface) mode, switch over to gnome, using the
|
|
command "switchdesk gnome", and then issue a
|
|
"startx" command to boot into the X Window System GUI
|
|
mode. Once into the GNOME environment, open the GNOME Terminal,
|
|
create a file named myapp.c using vi, and type in the following:</p>
|
|
|
|
<blockquote>
|
|
<p>/* A sample GNOME program<br>
|
|
Created By: Subhasish Ghosh<br>
|
|
Date: 8th August, 2001<br>
|
|
*/</p>
|
|
<p>#include <gnome.h></p>
|
|
<p>int main(int argc, char *argv[ ])<br>
|
|
{<br>
|
|
</p>
|
|
<blockquote>
|
|
<p>GtkWidget *ghosh;<br>
|
|
gnome_init("sample", "0.1", argc,
|
|
argv);<br>
|
|
ghosh = gnome_app_new("sample", "My
|
|
Window");<br>
|
|
gtk_widget_show(ghosh);</p>
|
|
<p>gtk_main();<br>
|
|
return 0;</p>
|
|
</blockquote>
|
|
<p>} </p>
|
|
</blockquote>
|
|
|
|
<p>Now, to compile the program myapp.c, make sure
|
|
you type in: (note the back-ticks carefully)</p>
|
|
|
|
<p><strong># gcc myapp.c -o myapp `gnome-config
|
|
--cflags --libs gnomeui`</strong></p>
|
|
|
|
<p>Note, GNOME comes with a shell script named <strong>gnome-config</strong>
|
|
that supplies the compiler with the correct flags required for
|
|
compilation. Once compiled, run the program using the command:</p>
|
|
|
|
<p><strong># ./myapp</strong> &<br>
|
|
and press enter.</p>
|
|
|
|
<p>An empty window will appear on the screen, which
|
|
you can move, resize, as well close. Now, let's take a closer
|
|
look at the code. At the top, we introduced a few commented
|
|
lines, describing the program, it's creator and date of creation.
|
|
Though not necessary, it's a good programming practice to include
|
|
those to each and every program. Then, we included the header
|
|
file, gnome.h, that takes care of all necessary GNOME and GTK+
|
|
library functions and definitions. Then comes "ghosh",
|
|
which is a GtkWidget pointer. This would point to our new Window
|
|
object. The function gnome_init is then called. It initializes
|
|
libraries, and is used for correct session management. The ID
|
|
passed to this gnome_init function is "sample", the
|
|
version number being "0.1", and then the usual command
|
|
line arguments of main. These are necessary for the internal
|
|
workings of GNOME. Then comes the function gnome_app_new(),
|
|
which when executed, creates our window. This takes two arguments,
|
|
as shown in the sample code: "sample" and "My
|
|
Window". "sample" is the application name,
|
|
and "My Window" is the window title. But please
|
|
note: Though the name of this function is gnome_app_new(); it
|
|
does NOT create any sort of new application or so. It creates a
|
|
top-level window, that's all. The next function called is
|
|
gtk_widget_show(), which makes our window visible. Next comes
|
|
gtk_main() which is a very important function, as it makes sure
|
|
that GNOME functions such as events nd button presses are executed, by
|
|
handing on the functionality to GNOME.</p>
|
|
|
|
<p>So, that's the internal workings of our first
|
|
GNOME program.</p>
|
|
|
|
<p><font size="5"><strong>5. </strong></font><a
|
|
name="Signals & Callbacks"><font size="5"><strong>Signals
|
|
& Callbacks</strong></font></a></p>
|
|
|
|
<p>Now let's take a deeper look into the GNOME
|
|
programming environment: "Signals" and
|
|
"Callbacks". What are these and what are they
|
|
used for? Do we really need them? Every single time the mouse
|
|
moves, enters and leaves widgets, buttons are pressed, toggle
|
|
buttons are toggled on or off, and such things are done, a signal
|
|
is sent to the application. This signal can be passed to a
|
|
callback function. So, though not always, yet at times,
|
|
applications need to connect to these events for taking certain
|
|
actions. In GNOME/GTK+, we call a function called
|
|
gtk_signal_connect to connect signals to handler functions.</p>
|
|
|
|
<p>The gtk_signal_connect function has the following
|
|
4 parameters:</p>
|
|
|
|
<ol>
|
|
<li><p>GtkObject *object -- Which widget the
|
|
callback is associated with.</p>
|
|
</li>
|
|
<li><p>const gchar *name -- The signal to be
|
|
handled.</p>
|
|
</li>
|
|
<li><p>GtkSignalFunc func -- The function to be
|
|
called when the signal is sent.</p>
|
|
</li>
|
|
<li><p>gpointer data -- Any arbitrary data to be
|
|
given to the signal handling function.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>It should be noted that various kinds of widgets
|
|
emit different signals. The signals from buttons are as follows:</p>
|
|
|
|
<ol>
|
|
<li><p>clicked -- Button clicked (pressed &
|
|
released).</p>
|
|
</li>
|
|
<li><p>pressed -- Button pressed down by mouse.</p>
|
|
</li>
|
|
<li><p>released -- Button released.</p>
|
|
</li>
|
|
<li><p>enter -- Mouse moved over the Button
|
|
area.</p>
|
|
</li>
|
|
<li><p>leave -- Mouse moved out of the Button
|
|
area.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>We will look into signals and callbacks playing a
|
|
vital role in the applications that we would develop later.</p>
|
|
|
|
<p><font size="5"><strong>6. </strong></font><a
|
|
name="Containers"><font size="5"><strong>Containers</strong></font></a></p>
|
|
|
|
<p>Next, we look into another vital component of
|
|
GNOME programming: containers. GTK+ uses containers a great deal,
|
|
because GTK+ is actually a "<strong>container-based</strong>"
|
|
toolkit. That means we have a parent container within which we
|
|
have to place our other widgets. Windows are single widget
|
|
containers. Thus, the important point to keep in mind is that
|
|
GTK+ utilizes invisible "packing boxes" which can hold
|
|
multiple widgets to create windows layouts. These "packing
|
|
boxes" are of two types: horizontal and vertical, created by
|
|
using the functionality of the functions gtk_hbox_new and
|
|
gtk_vbox_new, respectively. We would see these functions in
|
|
action soon, in the applications that we create later. For now,
|
|
let's take a look into the parameters of these two functions. They
|
|
have the following parameters:</p>
|
|
|
|
<ol>
|
|
<li><p><strong>homogeneous</strong> : type
|
|
--> gboolean : Forces all widgets in the box to occupy
|
|
the same area as the largest widget in the box. </p>
|
|
</li>
|
|
<li><p><strong>spacing</strong> : type -->
|
|
gint : Determines the space between adjacent widgets.</p>
|
|
</li>
|
|
<li><p><strong>expand</strong> : type -->
|
|
gboolean : Allows the packing box to expand to fill the
|
|
remaining space.</p>
|
|
</li>
|
|
<li><p><strong>fill</strong> : type -->
|
|
gboolean : Allows that particular widget to expand to
|
|
fill the remaining space.</p>
|
|
</li>
|
|
<li><p><strong>padding</strong> : type -->
|
|
gint : Determines the width of a frame surrounding the
|
|
widget.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p><font size="5"><strong>7. </strong></font><a
|
|
name="Buttons"><font size="5"><strong>Buttons</strong></font></a></p>
|
|
|
|
<p>Next we come to another very vital component:
|
|
Buttons. GTK+ provides 4 different kinds of buttons:</p>
|
|
|
|
<ol>
|
|
<li><p>Simple push buttons --> To perform an
|
|
action on clicking.</p>
|
|
</li>
|
|
<li><p>Toggle buttons --> With a particular
|
|
state: Up/Down</p>
|
|
</li>
|
|
<li><p>Check boxes --> With a particular
|
|
state: On/Off </p>
|
|
</li>
|
|
<li><p>Radio buttons --> For making only one
|
|
selection from a group of options.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>Creating radio buttons is very similar to check
|
|
boxes, and all that we need to do extra is to specify a group the
|
|
radio button belongs to. Radio buttons are derived from check
|
|
buttons, which are derived from toggle buttons, so this means
|
|
that we have the same set of functions to read and modify their
|
|
state and also use the same old events. Please note: For more
|
|
information of specific functions, consult the <em><strong>GTK+
|
|
Reference Documentation</strong></em> available at: <a
|
|
href="http://www.gtk.org">http://www.gtk.org</a></p>
|
|
|
|
<p><font size="5"><strong>8. </strong></font><a
|
|
name="Entry Widgets"><font size="5"><strong>Entry Widgets</strong></font></a></p>
|
|
|
|
<p>For creating single-line text widgets, which are
|
|
commonly called "Entry widgets", we utilize a function
|
|
called gtk_entry_new(). Entry widgets are mainly used to enter
|
|
small amounts of information. Let's know take a look at a program
|
|
that creates a "Login Window", and outputs the password
|
|
field, when the activate signal occurs, when the button is
|
|
pressed. Type in the following and execute the program as has
|
|
been explained above.</p>
|
|
|
|
<p>/* Creating a Login GNOME-style using GTK+
|
|
Toolkit:<br>
|
|
Created By: Subhasish Ghosh<br>
|
|
Date: Wednesday, August 8, 2001<br>
|
|
*/</p>
|
|
|
|
<p>#include <gnome.h></p>
|
|
|
|
<p>static void enter_pressed(GtkWidget *button,
|
|
gpointer data)<br>
|
|
{<br>
|
|
GtkWidget *text_entry = data;<br>
|
|
char *string = gtk_entry_get_text(GTK_ENTRY(text_entry));<br>
|
|
g_print(string);<br>
|
|
}</p>
|
|
|
|
<p>int main(int argc, char *argv[])<br>
|
|
{<br>
|
|
GtkWidget *app;<br>
|
|
GtkWidget *text_entry;<br>
|
|
GtkWidget *label;<br>
|
|
GtkWidget *hbox; gchar *text;</p>
|
|
|
|
<p>gnome_init("example", "0.1",
|
|
argc, argv);<br>
|
|
app = gnome_app_new("example", "entry
|
|
widget");<br>
|
|
gtk_container_border_width(GTK_CONTAINER(app), 5);</p>
|
|
|
|
<p>hbox = gtk_hbox_new(FALSE, 0);</p>
|
|
|
|
<p>/* we now create a Label: */<br>
|
|
label = gtk_label_new("Password: ");<br>
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 1.0);<br>
|
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);</p>
|
|
|
|
<p>text_entry = gtk_entry_new();<br>
|
|
gtk_entry_set_visibility(GTK_ENTRY(text_entry), FALSE);<br>
|
|
gtk_box_pack_start(GTK_BOX(hbox), text_entry, FALSE, FALSE, 0);</p>
|
|
|
|
<p>gtk_signal_connect(GTK_OBJECT(app),
|
|
"delete_event", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);<br>
|
|
gtk_signal_connect(GTK_OBJECT(text_entry), "activate",
|
|
GTK_SIGNAL_FUNC(enter_pressed), text_entry);</p>
|
|
|
|
<p>gnome_app_set_contents(GNOME_APP(app), hbox);<br>
|
|
gtk_widget_show_all(app);<br>
|
|
gtk_main( );<br>
|
|
return 0;<br>
|
|
}</p>
|
|
|
|
<p>This program when executed, a login window should
|
|
appear on the screen. Type in any text (assuming it to be a
|
|
password), press enter and observe what happens.</p>
|
|
|
|
<p><font size="5"><strong>9. </strong></font><a
|
|
name="List boxes and Combo boxes"><font size="5"><strong>List
|
|
boxes and Combo boxes</strong></font></a></p>
|
|
|
|
<p>List boxes and Combo boxes play the same role as
|
|
they play on the Microsoft platform. List box widgets hold a list
|
|
of strings that allow users to select one or more entries;
|
|
concerned the widget is so configured. Combo boxes are entry
|
|
widgets with an added pull-down menu that allow users to select
|
|
options also.</p>
|
|
|
|
<p><font size="5"><strong>10. </strong></font><a
|
|
name="Menus & Toolbars"><font size="5"><strong>Menus &
|
|
Toolbars</strong></font></a></p>
|
|
|
|
<p>The various widgets that we have come across
|
|
until now are simple widgets that don't provide some
|
|
extra-ordinary functionality. We now look at some specific GNOME
|
|
programming libraries that offer more complicated widgets with
|
|
rich functionality.</p>
|
|
|
|
<p>Just hang on for a second, someone may ask:
|
|
"Hey, we were doing pretty well with ordinary code and all
|
|
the stuff that you discussed earlier. What's the use of this
|
|
so-called "specific GNOME programming libraries"? Are
|
|
they indeed useful? Or are you just including them here for
|
|
making your article a bit longer?"</p>
|
|
|
|
<p>Well, here's the reason for considering specific
|
|
GNOME programming libraries. With plain GTK+ code, though nearly
|
|
everything can be done, which we usually would do using specific
|
|
GNOME programming libraries, but using simple and plain GTK+ code
|
|
often leads to much code repetition, inefficient code blocks and
|
|
such other things, making the whole program a bloated
|
|
one. Now, to prevent this from happening, we use specific GNOME
|
|
programming libraries that provide a great deal of extra
|
|
functionality and much lower programming overhead.</p>
|
|
|
|
<p>So, let's talk about "Menus" and
|
|
"Toolbars". GNOME lets us create menus
|
|
and toolbars for our GnomeApp widgets that can be docked and
|
|
undocked from the window. First you fill up arrays with the
|
|
necessary information, then call gnome_app_create_menus
|
|
or gnome_app_create_toolbar.</p>
|
|
|
|
<p>The menus and toolbar items each have properties, defined in
|
|
arrays.
|
|
A few such properties include type,
|
|
string, callback pointer, etc. Most of the time the menu
|
|
entries are pretty simple, and we can just use one of a set of
|
|
macros provided by GNOME to create the structure for us. So
|
|
let's check out a few of the most used top-level macros.</p>
|
|
|
|
<p>Please note: These macros are the ones
|
|
that create top-level menus when passed an array containing
|
|
any or all of the following GnomeUIInfo structures.</p>
|
|
<div align="center"><center>
|
|
|
|
<table border="3" cellpadding="4" cellspacing="4">
|
|
<tr>
|
|
<td align="center" bgcolor="#FFFFFF"><u>Menu</u></td>
|
|
<td align="center" bgcolor="#FFFFFF"><u>Macro</u></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">File</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_FILE_TREE(tree)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">Edit</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_EDIT_TREE(tree)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">View</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_VIEW_TREE(tree)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">Settings</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_SETTINGS_TREE(tree)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">Windows</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_WINDOWS_TREE(tree)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">Help</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_HELP_TREE(tree)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" bgcolor="#00FFFF">Game</td>
|
|
<td align="center" bgcolor="#00FFFF">GNOMEUIINFO_MENU_GAME_TREE(tree)</td>
|
|
</tr>
|
|
</table>
|
|
</center></div>
|
|
|
|
<p>Within the top-level menu there exists over
|
|
thirty macros for creating common menu items. The macros
|
|
associate small images (pixmaps) and accelerator keys with each
|
|
menu item. A callback function is required to be called when the
|
|
item is selected and a data pointer is to be passed to that
|
|
function.</p>
|
|
|
|
<p>Let's look at some of these common menu items and
|
|
their respective macros.</p>
|
|
|
|
<p><strong><u>File</u></strong> -->><br>
|
|
New --> GNOMEUIINFO_MENU_NEW_ITEM (label, hint, cb, data)<br>
|
|
Open --> GNOMEUIINFO_MENU_OPEN_ITEM (cb, data)<br>
|
|
Save --> GNOMEUIINFO_MENU_SAVE_ITEM (cb, data)<br>
|
|
Print --> GNOMEUIINFO_MENU_PRINT_ITEM (cb, data)<br>
|
|
Exit --> GNOMEUIINFO_MENU_EXIT_ITEM (cb, data)</p>
|
|
|
|
<p><strong><u>Edit</u></strong> -->><br>
|
|
Cut --> GNOMEUIINFO_MENU_CUT_ITEM (cb, data)<br>
|
|
Copy --> GNOMEUIINFO_MENU_COPY_ITEM (cb, data)<br>
|
|
Paste --> GNOMEUIINFO_MENU_PASTE_ITEM (cb, data)</p>
|
|
|
|
<p><strong><u>Settings</u></strong> -->><br>
|
|
Preferences --> GNOMEUIINFO_MENU_PREFERENCES_ITEM (cb, data)</p>
|
|
|
|
<p><strong><u>Help</u></strong> -->><br>
|
|
About --> GNOMEUIINFO_MENU_ABOUT_ITEM (cb, data)</p>
|
|
|
|
<p>Like menu bars, toolbars require an
|
|
array using the GNOMEUIINFO_ITEM_STOCK (label, tooltip, callback,
|
|
stock_id) macro. Here, "stock_id" is the id of a
|
|
predefined icon that we want to use for that item.</p>
|
|
|
|
<p>Let's look at this example, and see how the
|
|
arrays and macros work in reality.</p>
|
|
|
|
<p>#include <gnome.h></p>
|
|
|
|
<p>static void callback (GtkWidget *button, gpointer
|
|
data)<br>
|
|
{<br>
|
|
g_print("Item Selected");<br>
|
|
}</p>
|
|
|
|
<p>GnomeUIInfo file_menu[ ] = {<br>
|
|
GNOMEUIINFO_ITEM_NONE ("A menu item", "This is the
|
|
Status bar info", callback),<br>
|
|
GNOMEUIINFO_MENU_EXIT_ITEM (gtk_main_quit, NULL),<br>
|
|
GNOMEUIINFO_END<br>
|
|
};</p>
|
|
|
|
<p>GnomeUIInfo menubar[ ] = {<br>
|
|
GNOMEUIINFO_MENU_FILE_TREE (file_menu),<br>
|
|
GNOMEUIINFO_END<br>
|
|
};</p>
|
|
|
|
<p>GnomeUIInfo toolbar[ ] = {<br>
|
|
GNOMEUIINFO_ITEM_STOCK ("Print", "This is another
|
|
tooltip", callback, GNOME_STOCK_PIXMAP_PRINT),<br>
|
|
GNOMEUIINFO_ ITEM_STOCK ("Exit", "Exit the
|
|
application", gtk_main_quit, GNOME_STOCK_PIXMAP_EXIT),<br>
|
|
GNOMEUIINFO_END<br>
|
|
};</p>
|
|
|
|
<p>int main (int argc, char *argv[ ])<br>
|
|
{</p>
|
|
|
|
<p>GtkWidget *app;</p>
|
|
|
|
<p>gnome_init ("example", "0.1",
|
|
argc, argv);<br>
|
|
app = gnome_app_new ("example", "A Sample Toolbar
|
|
and Menu");</p>
|
|
|
|
<p>gnome_app_create_menus (GNOME_APP (app),
|
|
menubar);<br>
|
|
gnome_app_create_toolbar (GNOME_APP (app), toolbar);</p>
|
|
|
|
<p>gtk_widget_show_all (app);<br>
|
|
gtk_main();<br>
|
|
return 0;</p>
|
|
|
|
<p>}</p>
|
|
|
|
<p>This program creates a small window with
|
|
an embedded menu and toolbar. You can click,
|
|
dock, undock and drag it around the screen.</p>
|
|
|
|
<p><font size="5"><strong>11. </strong></font><a
|
|
name="Dialog boxes"><font size="5"><strong>Dialog boxes</strong></font></a></p>
|
|
|
|
<p>Let's now look at the widget that displays
|
|
textual information to the user in the GNOME environment. Yes, we
|
|
are referring to the Dialog box. When we need to create dialog
|
|
boxes, we call the gnome_message_box_new function and pass it the
|
|
message text, also mention the type of dialog box we need, and
|
|
the buttons we want on it. All of this mentioned in a NULL
|
|
terminated list. Then we bind the "clicked" signal of
|
|
the dialog widget that we have just created to a handling
|
|
function that is passed the button that the user pressed as an
|
|
integer. Finally, we call the gtk_widget_show function for
|
|
displaying a non-modal box.</p>
|
|
|
|
<p>Let's look at this code extract from a program,
|
|
which creates a simple question dialog box, adds three buttons
|
|
and responds to the user's code.</p>
|
|
|
|
<p>static void messagebox_clicked(GnomeDialog *dlg,
|
|
gint button, gpointer data)<br>
|
|
{</p>
|
|
|
|
<p>switch (button)<br>
|
|
{</p>
|
|
|
|
<p>case 1: /* user pressed apply */ <br>
|
|
return;</p>
|
|
|
|
<p>case 0: /* user pressed ok */</p>
|
|
|
|
<p>case 2: /* user pressed close */<br>
|
|
gnome_dialog_close(dlg);</p>
|
|
|
|
<p>}</p>
|
|
|
|
<p>}</p>
|
|
|
|
<p>GtkWidget *dlg;</p>
|
|
|
|
<p>dlg = gnome_message_box_new("Hi, pal, how
|
|
are you doing??? I am fine!",<br>
|
|
GNOME_MESSAGE_BOX_QUESTION,<br>
|
|
GNOME_STOCK_BUTTON_OK,<br>
|
|
GNOME_STOCK_BUTTON_APPLY,<br>
|
|
GNOME_STOCK_BUTTON_CLOSE,<br>
|
|
NULL);</p>
|
|
|
|
<p>gtk_signal_connect (GTK_OBJECT(dlg),
|
|
"clicked", GTK_SIGNAL_FUNC(messagebox_clicked), NULL);</p>
|
|
|
|
<p>gtk_widget_show (dlg);</p>
|
|
|
|
<p><font size="5"><strong>12. </strong></font><a
|
|
name="Conclusion & Links for Further study"><font size="5"><strong>Conclusion
|
|
& Links for Further study</strong></font></a></p>
|
|
|
|
<p>This sums up our journey of the exciting world of
|
|
GNOME programming using GTK+ toolkit.</p>
|
|
|
|
|
|
<p>Please note: GNOME Programming is not at all
|
|
difficult. Once you have a little understanding, it's
|
|
really easy to grasp. There is still much more to learn after this
|
|
article, but if done diligently, it can definitely be mastered.</p>
|
|
|
|
<p>For more information and detailed coverage of
|
|
this topic, check out the following links: </p>
|
|
|
|
<p><a
|
|
href="http://www.linuxheadquarters.com/howto/programming/gtk_examples/index.shtml">http://www.linuxheadquarters.com/howto/programming/gtk_examples/index.shtml</a></p>
|
|
|
|
<p><a
|
|
href="http://www.ibiblio.org/pub/Linux/docs/HOWTO/mini/other-formats/html_single/Programming-Languages.html">http://www.ibiblio.org/pub/Linux/docs/HOWTO/mini/other-formats/html_single/Programming-Languages.html</a></p>
|
|
|
|
<p><a
|
|
href="http://linuxheadquarters.com/howto/programming/gtk_examples/window/window.shtml">http://linuxheadquarters.com/howto/programming/gtk_examples/window/window.shtml</a></p>
|
|
|
|
<p><a
|
|
href="http://developer.gnome.org/doc/GGAD/ggad.html">http://developer.gnome.org/doc/GGAD/ggad.html</a></p>
|
|
|
|
<p><a
|
|
href="http://wolfpack.twu.net/docs/gtkdnd/index.html">http://wolfpack.twu.net/docs/gtkdnd/index.html</a></p>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- *** BEGIN bio *** -->
|
|
<SPACER TYPE="vertical" SIZE="30">
|
|
<P>
|
|
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Subhasish Ghosh</H4>
|
|
<EM>I am
|
|
20 years old, currently a computer-systems engineering student in
|
|
India. I am a Microsoft Certified Professional (MCP), MSCD, MCP
|
|
certified on NT 4.0, recently completed Red Hat Linux Certified
|
|
Engineer (RHCE) Training. I have been working with Linux for a
|
|
long time, have had programmed using C, C++, VC++, VB, COM, DCOM,
|
|
MFC, ATL 3.0, Perl, Python and Linux programming using GTK+.
|
|
Currently busy learning the Linux kernel Architecture in detail
|
|
and doing Linux kernel Programming. </EM>
|
|
|
|
<!-- *** END bio *** -->
|
|
|
|
<!-- *** BEGIN copyright *** -->
|
|
<P> <hr> <!-- P -->
|
|
<H5 ALIGN=center>
|
|
|
|
Copyright © 2001, Subhasish Ghosh.<BR>
|
|
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
|
|
Published in Issue 70 of <i>Linux Gazette</i>, September 2001</H5>
|
|
<!-- *** END copyright *** -->
|
|
|
|
<!--startcut ==========================================================-->
|
|
<HR><P>
|
|
<CENTER>
|
|
<!-- *** BEGIN navbar *** -->
|
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="ghosh.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue70/ghosh2.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="mcgucken.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
|
<!-- *** END navbar *** -->
|
|
</CENTER>
|
|
</BODY></HTML>
|
|
<!--endcut ============================================================-->
|