162 lines
7.3 KiB
HTML
162 lines
7.3 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<title>Building user interfaces: GTK+ 3 Reference Manual</title>
|
||
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
||
<link rel="home" href="index.html" title="GTK+ 3 Reference Manual">
|
||
<link rel="up" href="gtk-getting-started.html" title="Getting Started with GTK+">
|
||
<link rel="prev" href="ch01s02.html" title="Packing">
|
||
<link rel="next" href="ch01s04.html" title="Building applications">
|
||
<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)">
|
||
<link rel="stylesheet" href="style.css" type="text/css">
|
||
</head>
|
||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
|
||
<td width="100%" align="left" class="shortcuts"></td>
|
||
<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
|
||
<td><a accesskey="u" href="gtk-getting-started.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
|
||
<td><a accesskey="p" href="ch01s02.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
|
||
<td><a accesskey="n" href="ch01s04.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
|
||
</tr></table>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="id-1.2.3.11"></a>Building user interfaces</h2></div></div></div>
|
||
<p>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.</p>
|
||
<p>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 <a class="link" href="GtkBuilder.html" title="GtkBuilder"><span class="type">GtkBuilder</span></a> class.</p>
|
||
<div class="example">
|
||
<a name="id-1.2.3.11.4"></a><p class="title"><b>Example 3. Packing buttons with GtkBuilder</b></p>
|
||
<div class="example-contents">
|
||
<p>Create a new file with the following content named example-3.c.</p>
|
||
<pre class="programlisting">#include <gtk/gtk.h>
|
||
|
||
static void
|
||
print_hello (GtkWidget *widget,
|
||
gpointer data)
|
||
{
|
||
g_print ("Hello World\n");
|
||
}
|
||
|
||
int
|
||
main (int argc,
|
||
char *argv[])
|
||
{
|
||
GtkBuilder *builder;
|
||
GObject *window;
|
||
GObject *button;
|
||
GError *error = NULL;
|
||
|
||
gtk_init (&argc, &argv);
|
||
|
||
/* Construct a GtkBuilder instance and load our UI description */
|
||
builder = gtk_builder_new ();
|
||
if (gtk_builder_add_from_file (builder, "builder.ui", &error) == 0)
|
||
{
|
||
g_printerr ("Error loading file: %s\n", error->message);
|
||
g_clear_error (&error);
|
||
return 1;
|
||
}
|
||
|
||
/* Connect signal handlers to the constructed widgets. */
|
||
window = gtk_builder_get_object (builder, "window");
|
||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||
|
||
button = gtk_builder_get_object (builder, "button1");
|
||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||
|
||
button = gtk_builder_get_object (builder, "button2");
|
||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||
|
||
button = gtk_builder_get_object (builder, "quit");
|
||
g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
|
||
|
||
gtk_main ();
|
||
|
||
return 0;
|
||
}
|
||
</pre>
|
||
<p>Create a new file with the following content named builder.ui.</p>
|
||
<pre class="programlisting"><interface>
|
||
<object id="window" class="GtkWindow">
|
||
<property name="visible">True</property>
|
||
<property name="title">Grid</property>
|
||
<property name="border-width">10</property>
|
||
<child>
|
||
<object id="grid" class="GtkGrid">
|
||
<property name="visible">True</property>
|
||
<child>
|
||
<object id="button1" class="GtkButton">
|
||
<property name="visible">True</property>
|
||
<property name="label">Button 1</property>
|
||
</object>
|
||
<packing>
|
||
<property name="left-attach">0</property>
|
||
<property name="top-attach">0</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object id="button2" class="GtkButton">
|
||
<property name="visible">True</property>
|
||
<property name="label">Button 2</property>
|
||
</object>
|
||
<packing>
|
||
<property name="left-attach">1</property>
|
||
<property name="top-attach">0</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object id="quit" class="GtkButton">
|
||
<property name="visible">True</property>
|
||
<property name="label">Quit</property>
|
||
</object>
|
||
<packing>
|
||
<property name="left-attach">0</property>
|
||
<property name="top-attach">1</property>
|
||
<property name="width">2</property>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
<packing>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
</interface>
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
<br class="example-break"><p>
|
||
You can compile the program above with GCC using:
|
||
</p>
|
||
<div class="literallayout"><p><br>
|
||
<code class="literal">gcc `pkg-config --cflags gtk+-3.0` -o example-3 example-3.c `pkg-config --libs gtk+-3.0`</code><br>
|
||
</p></div>
|
||
<p>
|
||
</p>
|
||
<p>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
|
||
<a class="link" href="GtkBuilder.html#gtk-builder-get-object" title="gtk_builder_get_object ()"><code class="function">gtk_builder_get_object()</code></a> and returns a GObject* instead of a
|
||
GtkWidget*.</p>
|
||
<p>Normally, you would pass a full path to
|
||
<a class="link" href="GtkBuilder.html#gtk-builder-add-from-file" title="gtk_builder_add_from_file ()"><code class="function">gtk_builder_add_from_file()</code></a> to make the execution of your program
|
||
independent of the current directory. A common location to install
|
||
UI descriptions and similar data is
|
||
<code class="filename">/usr/share/<em class="replaceable"><code>appname</code></em></code>.
|
||
</p>
|
||
<p>It is also possible to embed the UI description in the source
|
||
code as a string and use <a class="link" href="GtkBuilder.html#gtk-builder-add-from-string" title="gtk_builder_add_from_string ()"><code class="function">gtk_builder_add_from_string()</code></a> 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 <a class="ulink" href="http://glade.gnome.org" target="_top">glade</a>
|
||
can load the file and allow you to create and modify your UI by
|
||
point-and-click.</p>
|
||
</div>
|
||
<div class="footer">
|
||
<hr>Generated by GTK-Doc V1.33.1</div>
|
||
</body>
|
||
</html> |