/usr/share/help/gl/gnome-devel-demos/image-viewer.cpp.page is in gnome-devel-docs 3.28.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | <?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="image-viewer.cpp" xml:lang="gl">
<info>
<link type="guide" xref="cpp#examples"/>
<desc>Un pouco máis que un simple aplicativo Gtkmm «Ola mundo».</desc>
<revision pkgversion="0.1" version="0.1" date="2011-03-18" status="review"/>
<credit type="author">
<name>Proxecto de documentación de GNOME</name>
<email its:translate="no">gnome-doc-list@gnome.org</email>
</credit>
<credit type="author">
<name>Johannes Schmid</name>
<email its:translate="no">jhs@gnome.org</email>
</credit>
<credit type="editor">
<name>Marta Maria Casetti</name>
<email its:translate="no">mmcasetti@gmail.com</email>
<years>2013</years>
</credit>
<mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
<mal:name>Fran Dieguez</mal:name>
<mal:email>frandieguez@gnome.org</mal:email>
<mal:years>2012-2013.</mal:years>
</mal:credit>
</info>
<title>Image viewer</title>
<synopsis>
<p>Neste titorial aprenderá:</p>
<list>
<item><p>Algúns conceptos básicos de programación de C++/GObject</p></item>
<item><p>Cómo escribir un aplicativo GTK en C++</p></item>
</list>
</synopsis>
<media type="image" mime="image/png" src="media/image-viewer.png"/>
<section id="anjuta">
<title>Cree un proxecto de Anjuta</title>
<p>Antes de comezar a programar, deberá configurar un proxecto novo en Anjuta. Isto creará todos os ficheiros que precise para construír e executar o código máis adiante. Tamén é útil para manter todo ordenado.</p>
<steps>
<item>
<p>Inicie Anjuta e prema <guiseq><gui>Ficheiro</gui><gui>Novo</gui><gui>Proxecto</gui></guiseq> para abrir o asistente de proxectos.</p>
</item>
<item>
<p>Seleccione <gui>GTK+ (Simple)</gui> desde a lapela <gui>C++</gui>, prema <gui>Adiante</gui> e complete os detalles nas seguintes páxinas. Use <file>image-viewer</file> como nome do proxecto e cartafol.</p>
</item>
<item>
<p>Asegúrese que <gui>Usar GtkBuilder para a interface de usuario</gui> está desactivado xa que crearemos a UI manualmente neste titorial. Comprobe o titorial <link xref="guitar-tuner.cpp">Guitar-Tuner</link> se quere aprender como usar o construtor de interface.</p>
</item>
<item>
<p>Prema <gui>Aplicar</gui> para crear o proxecto. Abra <file>src/main.cc</file> desde as lapelas <gui>Proxecto</gui> ou <gui>Ficheiro</gui>. Debería ver algún código que comeza coas liñas:</p>
<code mime="text/x-csrc"><![CDATA[
#include <gtkmm.h>
#include <iostream>
#include "config.h">]]></code>
</item>
</steps>
</section>
<section id="build">
<title>Construír o código por primeira vez</title>
<p>This is a very basic C++ code setting up GTKmm. More details are given below; skip this list if you understand the basics:</p>
<list>
<item>
<p>The three <code>#include</code> lines at the top include the <code>config</code> (useful autoconf build defines), <code>gtkmm</code> (user interface) and <code>iostream</code> (C++-STL) libraries. Functions from these libraries are used in the rest of the code.</p>
</item>
<item>
<p>A función <code>main</code> crea unha xanela nova (e baleira) e estabelece o título da xanela.</p>
</item>
<item>
<p>The <code>kit::run()</code> call starts the GTKmm main loop, which runs the user interface and starts listening for events (like clicks and key presses). As we give the window
as an argument to that function, the application will automatically exit when
that window is closed.</p>
</item>
</list>
<p>This code is ready to be used, so you can compile it by clicking <guiseq><gui>Build</gui><gui>Build Project</gui></guiseq> (or press <keyseq><key>Shift</key><key>F7</key></keyseq>).</p>
<p>Prema <gui>Executar</gui> na seguinte xanela que aparece para configurar a compilación de depuración. Só precisa facer isto unha vez para a primeira compilación.</p>
</section>
<section id="ui">
<title>Crear a interface de usuario</title>
<p>Now we will bring life into the empty window. GTKmm organizes the user interface
with <code>Gtk::Container</code>s that can contain other widgets and even other containers. Here we
will use the simplest available container, a <code>Gtk::Box</code>:</p>
<code mime="text/x-csrc"><![CDATA[
int
main (int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Gtk::Window main_win;
main_win.set_title ("image-viewer-cpp");
Gtk::Box* box = Gtk::manage(new Gtk::Box());
box->set_orientation (Gtk::ORIENTATION_VERTICAL);
box->set_spacing(6);
main_win.add(*box);
image = Gtk::manage(new Gtk::Image());
box->pack_start (*image, true, true);
Gtk::Button* button = Gtk::manage(new Gtk::Button("Open Image…"));
button->signal_clicked().connect (
sigc::ptr_fun(&on_open_image));
box->pack_start (*button, false, false);
main_win.show_all_children();
kit.run(main_win);
return 0;
}
]]></code>
<steps>
<item>
<p>The first lines create the widgets we want to use: a button for opening up an image, the image view widget itself and the box we will use as a container. </p>
</item>
<item>
<p>The calls to <code>pack_start</code> add the two widgets to the box and define their behaviour. The image will
expand into any available space while the button will just be as big as needed. You will notice that we don't set
explicit sizes on the widgets. In GTKmm this is usually not needed as it makes it much easier to have a layout that
looks good in different window sizes. Next, the box is added to the window.</p>
</item>
<item>
<p>We need to define what happens when the user clicks on the button. GTKmm uses the concept of <em>signals</em>. When the button is clicked, it fires the <em>clicked</em> signal, which we can connect to some action. This is done using the <code>signal_clicked().connect</code>
method which tells GTKmm to call the <code>on_open_image</code> function when the button is clicked. We will define the <em>callback</em> in the next section.</p>
</item>
<item>
<p>The last step is to show all widgets in the window using
<code>show_all_children()</code>. This is equivalent to using the <code>show()</code>
method on all our child widgets.</p>
</item>
</steps>
</section>
<section id="show">
<title>Mostrar a imaxe</title>
<p>We will now define the signal handler for the <em>clicked</em> signal or the
button we mentioned before. Add this code before the <code>main</code>
method.</p>
<code mime="text/x-csrc"><![CDATA[
Gtk::Image* image = 0;
static void
on_open_image ()
{
Gtk::FileChooserDialog dialog("Open image",
Gtk::FILE_CHOOSER_ACTION_OPEN);
dialog.add_button (Gtk::Stock::OPEN,
Gtk::RESPONSE_ACCEPT);
dialog.add_button (Gtk::Stock::CANCEL,
Gtk::RESPONSE_CANCEL);
Glib::RefPtr<Gtk::FileFilter> filter =
Gtk::FileFilter::create();
filter->add_pixbuf_formats();
filter->set_name("Images");
dialog.add_filter (filter);
const int response = dialog.run();
dialog.hide();
switch (response)
{
case Gtk::RESPONSE_ACCEPT:
image->set(dialog.get_filename());
break;
default:
break;
}
}
]]></code>
<p>This is a bit more complicated than anything we've attempted so far, so let's break it down:</p>
<list>
<item>
<p>The dialog for choosing the file is created using the
<code>Gtk::FileChooserDialog</code> constructor. This takes the title and type of the dialog. In our case, it is an <em>Open</em> dialog.</p>
</item>
<item>
<p>The next two lines add an <em>Open</em> and a <em>Close</em> button to the dialog.</p>
<p>Notice that we are using <em>stock</em> button names from Gtk, instead of manually typing "Cancel" or "Open". The advantage of using stock names is that the button labels will already be translated into the user's language.</p>
<p>The second argument to the <code>add_button()</code> method is a value to identify
the clicked button. We use predefined values provided by GTKmm here, too.
</p>
</item>
<item>
<p>The next two lines restrict the <gui>Open</gui> dialog to only display files which can be opened by <code>Gtk::Image</code>. A filter object is created first; we then add all kinds of files supported by <code>Gdk::Pixbuf</code> (which includes most image formats like PNG and JPEG) to the filter. Finally, we set this filter to be the <gui>Open</gui> dialog's filter.</p>
<p><code>Glib::RefPtr</code> is a smart pointer used here, that makes sure that the filter is
destroyed when there is no reference to it anymore.</p>
</item>
<item>
<p><code>dialog.run</code> displays the <gui>Open</gui> dialog. The dialog will wait for the user to choose an image; when they do, <code>dialog.run</code> will return the value <code>Gtk::RESPONSE_ACCEPT</code> (it would return <code>Gtk::RESPONSE_CANCEL</code> if the user clicked <gui>Cancel</gui>). The <code>switch</code> statement tests for this.</p>
</item>
<item>
<p>We hide the <gui>Open</gui> dialog because we don't need it any more. The dialog would be hidden later anyway, as it is only a local variable and is
destroyed (and therefore hidden) when the scope ends.</p>
</item>
<item><p>Assuming that the user did click <gui>Open</gui>, the next line loads the
file into the <code>Gtk::Image</code> so that it is displayed.</p>
</item>
</list>
</section>
<section id="build2">
<title>Construír e executar o aplicativo</title>
<p>All of the code should now be ready to go. Click <guiseq><gui>Build</gui><gui>Build Project</gui></guiseq> to build everything again, and then <guiseq><gui>Run</gui><gui>Execute</gui></guiseq> to start the application.</p>
<p>Se non o fixo aínda, seleccione o aplicativo <file>Debug/src/image-viewer</file> no diálogo que aparece. Finalmente, prema <gui>Executar</gui> e desfrute!</p>
</section>
<section id="impl">
<title>Implementación de referencia</title>
<p>Se ten problemas con este titorial, compare o seu código con este <link href="image-viewer/image-viewer.cc">código de referencia</link>.</p>
</section>
<section id="next">
<title>Seguintes pasos</title>
<p>Aquí hai algunhas ideas sobre como pode estender esta sinxela demostración:</p>
<list>
<item>
<p>Have the user select a directory rather than a file, and provide controls to cycle through all of the images in a directory.</p>
</item>
<item>
<p>Aplicar filtros aleatorios e efectos á imaxe cando se carga e permitir ao usuario gardar a imaxe modificada.</p>
<p><link href="http://www.gegl.org/api.html">GEGL</link> fornece capacidades moi potentes de manipulación de imaxes.</p>
</item>
<item>
<p>Permitir ao usuario cargar imaxes desde recursos de rede compartidos, escáneres e outras fontes máis complicadas.</p>
<p>You can use <link href="http://library.gnome.org/devel/gio/unstable/">GIO</link> to handle network file transfers and the like, and <link href="http://library.gnome.org/devel/gnome-scan/unstable/">GNOME Scan</link> to handle scanning.</p>
</item>
</list>
</section>
</page>
|