Blob Blame History Raw
<?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.vala" xml:lang="cs">

  <info>
  <title type="text">Prohlížeč obrázků (Vala)</title>
    <link type="guide" xref="vala#examples"/>

    <desc>O trošku složitější aplikace GTK+ než jednoduché „Hello world“.</desc>

    <revision pkgversion="0.1" version="0.1" date="2011-03-18" status="review"/>
    <credit type="author">
      <name>Dokumentační projekt 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="author">
      <name>Philip Chimento</name>
      <email its:translate="no">philip.chimento@gmail.com</email>
    </credit>
    <credit type="editor">
     <name>Tiffany Antopolski</name>
     <email its:translate="no">tiffany.antopolski@gmail.com</email>
    </credit>
  <credit type="editor">
    <name>Marta Maria Casetti</name>
    <email its:translate="no">mmcasetti@gmail.com</email>
    <years>2013</years>
  </credit>
  </info>

<title>Prohlížeč obrázků</title>
<synopsis>
  <p>V této lekci vytvoříte aplikaci, která otevře a zobrazí soubor s obrázkem. Naučíte se:</p>
  <list type="numbered">
    <item><p>Jak vytvořit základní projekt pomocí <link xref="getting-ready">IDE Anjuta</link>.</p></item>
    <item><p>Jak napsat <link href="http://developer.gnome.org/platform-overview/stable/gtk">aplikaci Gtk</link> v jazyce Vala.</p></item>
    <item><p>Některé základní koncepty programování s <link href="http://developer.gnome.org/gobject/stable/">GObject</link></p></item>

  </list>
  <p>Abyste mohli pokračovat v této lekci, budete potřebovat následující:</p>
  <list>
    <item><p>Základní znalosti programovacího jazyka <link href="https://live.gnome.org/Vala/Tutorial">Vala</link>.</p></item>
    <item><p>Nainstalovanou kopii vývojářského studia <app>Anjuta</app>.</p></item>
    <item><p>Může se vám hodit referenční příručka k API <link href="http://valadoc.org/gtk+-3.0/">gtk+-3.0</link>, ačkoliv pro tuto výuku není nutná.</p></item>
  </list>
</synopsis>

<media type="image" mime="image/png" src="media/image-viewer.png"/>

<section id="anjuta">
  <title>Vytvoření projektu ve studiu Anjuta</title>
  <p>Než začnete s kódováním, musíte ve studiu Anjuta vytvořit nový projekt. Tím se vytvoří všechny soubory, které budete později potřebovat k sestavení a spuštění kódu. Je to také užitečné kvůli udržení všeho pohromadě.</p>
  <steps>
    <item>
      <p>Spusťte aplikaci <app>Anjuta</app> a klikněte na  <gui>Vytvořit nový projekt</gui> nebo <guiseq><gui>Soubor</gui> <gui>Nový</gui> <gui>Projekt</gui></guiseq>, aby se otevřel průvodce projektem.</p>
    </item>
    <item>
      <p>Na kartě <gui>Vala</gui> zvolte <gui>GTK+ (jednoduchý)</gui>. Klikněte na <gui>Pokračovat</gui> a na několika následujících stránkách vyplňte své údaje. Jako název projektu a složky použijte <file>image-viewer</file>.</p>
   	</item>
    <item>
      <p>Ujistěte se, že <gui>Použít GtkBuilder k tvorbě uživatelského rozhraní</gui> je vypnuto, protože jej chceme v této lekci vytvořit ručně.</p>
     <note><p>Jak používat builder k tvorbě rozhraní se můžete naučit v lekci <link xref="guitar-tuner.vala">Kytarová ladička</link>.</p></note>
    </item>
    <item>
      <p>Klikněte na <gui>Pokračovat</gui> a pak na <gui>Použít</gui> a vytvoří se vám projekt. Otevřete <file>src/image_viewer.vala</file> na kartě <gui>Projekt</gui> nebo <gui>Soubor</gui>. Měli byste vidět kód, který začíná řádky:</p>
      <code mime="text/x-csharp">
using GLib;
using Gtk;

public class Main : Object
{

	public Main ()
	{
		Window window = new Window();
		window.set_title ("Hello World");
		window.show_all();
		window.destroy.connect(on_destroy);
	}

	public void on_destroy (Widget window)
	{
		Gtk.main_quit();
	}

	static int main (string[] args)
	{
		Gtk.init (ref args);
		var app = new Main ();

		Gtk.main ();

		return 0;
	}
}</code>
    </item>
  </steps>
</section>

<section id="build">
  <title>Prvotní sestavení kódu</title>
  <p>Kód načte (prázdné) okno ze souboru s popisem uživatelského rozhraní a zobrazí jej. Dále to podrobněji rozebereme. Pokud jste již pochopili základy, tak tento seznam můžete přeskočit:</p>

  <list>
    <item>
      <p>Dva řádky <code>using</code> v horní části naimportují jmenné prostory, abychom je nemuseli výslovně uvádět.</p>
    </item>
    <item>
      <p>Konstruktor třídy <code>Main</code> vytvoří nové (prázdné) okno a napojí <link href="https://live.gnome.org/Vala/SignalsAndCallbacks">signál</link>, aby se aplikace ukončila, když se zavře okno.</p>
      <p>Napojení signálu je způsob, jak definovat, co se má stát, když zmáčknete tlačítko nebo se prostě něco přihodí. Zde je zavolána metoda <code>destroy</code> (a ukončení aplikace) při zavření okna.</p>
    </item>
    <item>
      <p>Funkce <code>static main</code> se spustí jako výchozí, když spustíte aplikaci napsanou v jazyce Vala. Volá pár funkcí, které vytvoří třídu <code>Main</code> a nastaví a spustí aplikaci. Funkce <link href="http://valadoc.org/gtk+-3.0/Gtk.main.html"><code>Gtk.main</code></link> spustí <link href="http://en.wikipedia.org/wiki/Event_loop">hlavní smyčku</link> GTK, která spustí uživatelské rozhraní a začne naslouchat událostem (jako je kliknutí nebo zmáčknutí klávesy).</p>
    </item>
  </list>

  <p>Kód je připravený k použití, takže jej můžete zkompilovat kliknutím na <guiseq><gui>Sestavit</gui> <gui>Sestavit projekt</gui></guiseq> (nebo zmáčknutím <keyseq><key>Shift</key> <key>F7</key></keyseq>).</p>
  <p>Změňte <gui>Konfiguraci</gui> na <gui>Výchozí</gui> a klikněte na <gui>Spustit</gui>, aby se nakonfigurovala složka, ve které se provádí sestavení. Stačí to udělat jen jednou, pro první sestavení.</p>
</section>

<section id="ui">
  <title>Vytvoření uživatelského rozhraní</title>
  <p>Nyní prázdné okno oživíme. GTK uspořádává uživatelské rozhraní pomocí widgetů <link href="http://www.valadoc.org/gtk+-2.0/Gtk.Container.html"><code>Gtk.Container</code></link>, které mohou obsahovat další widgety i další kontejnery. Zde použijeme nejjednodušší dostupný kontejner <link href="http://unstable.valadoc.org/gtk+-2.0/Gtk.Box.html"><code>Gtk.Box</code></link>.</p>

<p>Přidejte následující řádky na začátek třídy <code>Main</code>:</p>
  <code mime="text/x-csharp">
private Window window;
private Image image;
</code>

<p>Nyní nahraďte současný konstruktor tímto uvedeným níže:</p>
<code mime="text/x-csharp">

public Main () {

	window = new Window ();
	window.set_title ("Image Viewer in Vala");

	// Nastaví uživatelské rozhraní
	var box = new Box (Orientation.VERTICAL, 5);
	var button = new Button.with_label ("Open image");
	image = new Image ();

	box.pack_start (image, true, true, 0);
	box.pack_start (button, false, false, 0);
	window.add (box);

	// Zobrazí dialogové okno při otevírání souboru
	button.clicked.connect (on_open_image);

	window.show_all ();
	window.destroy.connect (main_quit);
}
</code>
  <steps>
    <item>
      <p>První dva řádky jsou částí GUI a budeme k nim potřebovat přístup z více než jedné metody. Proto je deklarujeme zde, takže budou přístupné skrze třídu. Jinak by byly přístupné jen v metodě, kde by byly vytvořeny.</p>
    </item>
    <item>
      <p>První řádek konstruktoru vytvoří prázdné okno. Následující řádky vytvoří widgety, které chceme používat: tlačítko pro otevření obrázku, vlastní widget pro zobrazení obrázku a box sloužící jako kontejner.</p>
    </item>
    <item>
      <p>Volání <link href="http://unstable.valadoc.org/gtk+-2.0/Gtk.Box.pack_start.html"><code>pack_start</code></link> přidává dva widgety do boxu a definuje jejich chování. Obrázek se roztáhne přes veškeré dostupné místo, zatímco tlačítko bude jen tak velké, jak je potřeba. Všimněte si, že jsem u widgetů výslovně nenastavili velikost. GTK to obvykle nepotřebuje, což usnadňuje udělat rozvržení, které vypadá dobře při různých velikostech okna. Následně je box přidán do okna.</p>
    </item>
    <item>
      <p>Potřebujeme nadefinovat, co se stane, když uživatel klikne na tlačítko. GTK používá koncept <em>signálů</em>.</p>
      <p>Když je kliknuto na <link href="http://valadoc.org/gtk+-3.0/Gtk.Button.html">button</link>, vyšle se signál <link href="http://valadoc.org/gtk+-3.0/Gtk.Button.clicked.html"><code>clicked</code></link>, který může být napojen na nějakou akci (definovanou v metodě <link href="https://live.gnome.org/Vala/SignalsAndCallbacks">zpětného volání</link>).</p>
      <p>To se udělá pomocí metody <code>connect</code> signálu <code>clicked</code> u tlačítka, což v tomto případě řekne GTK, aby ve chvíli, kdy je na tlačítko kliknuto, zavolalo (zatím nenadefinovanou) metodu zpětného volání <code>on_image_open</code>. <em>Zpětné volání</em> nadefinujeme v další části.</p>
      <p>Ve zpětném volání potřebujeme přístup k widgetům <code>window</code> a <code>image</code>, což je důvod, proč je definujeme jako soukromé členy na začátku naší třídy.</p>
    </item>
    <item>
      <p>Poslední volání funkce <code>connect</code> zajistí, že se aplikace ukončí, když je zavřeno okno. Kód, který vygenerovala Anjuta, volá metodu zpětného volání <code>on_destroy</code>, která volá  <link href="http://www.valadoc.org/gtk+-2.0/Gtk.main_quit.html"><code>Gtk.main_quit</code></link>, ale prosté napojení signálu na <code>main_quit</code> je jednodušší. Metodu <code>on_destroy</code> můžete smazat.</p>
    </item>
  </steps>
</section>

<section id="image">
  <title>Zobrazení obrázku</title>
  <p>Nyní nadefinujeme obsluhu signálu pro signál <em>clicked</em> tzn. pro tlačítko zmíněné dříve. Přidejte tento kód za konstruktor:</p>
  <code mime="text/x-csharp">
public void on_open_image (Button self) {
	var filter = new FileFilter ();
	var dialog = new FileChooserDialog ("Open image",
	                                    window,
	                                    FileChooserAction.OPEN,
	                                    Stock.OK,     ResponseType.ACCEPT,
	                                    Stock.CANCEL, ResponseType.CANCEL);
	filter.add_pixbuf_formats ();
	dialog.add_filter (filter);

	switch (dialog.run ())
	{
		case ResponseType.ACCEPT:
			var filename = dialog.get_filename ();
			image.set_from_file (filename);
			break;
		default:
			break;
	}
	dialog.destroy ();
}
</code>
  <p>Toto je trochu složitější, takže si to pojďme rozebrat:</p>
  <note><p>Obsluha signálu je typ metody zpětného volání, která je volána, když je vyslán signál. Běžně se k označní používají oba termíny.</p></note>
  <list>
    <item>
      <p>Prvním argumentem metody zpětného volání je vždy widget, který signál vyslal. Někdy za ním může následovat další argument související se signálem, ale <em>clicked</em> žádný nemá.</p>
      <p>V tomto případě <code>button</code> vyšle signál <code>clicked</code>, který je napojen na metodu zpětného volání <code>on_open_image</code>:</p>
<code mime="text/x-csharp">
        button.clicked.connect (on_open_image);
</code>

  <p>Metoda <code>on_open_image</code> přebírá jako argument tlačítko, které vyslalo signál:</p>
 <code mime="text/x-csharp">
        public void on_open_image (Button self)
</code>
    </item>
    <item>
      <p>Dalším zajímavým řádkem je ten, kde je vytvořeno dialogové okno pro výběr souboru. Konstruktor widgetu <link href="http://www.valadoc.org/gtk+-3.0/Gtk.FileChooserDialog.html"><code>FileChooserDialog</code></link> přebírá název do záhlaví dialogového okna, rodičovské okno a několik voleb, jako je počet tlačítek a jim odpovídající hodnoty.</p>
      <p>Všimněte si, že používáme <link href="http://unstable.valadoc.org/gtk+-3.0/Gtk.Stock.html"><em>standardní</em></link> názvy tlačítek z Gtk, místo abychom ručně psali „Cancel“ nebo „Open“. Výhodou použití standardních názvů je, že popisky tlačítek budou vždy přeloženy do uživatelova jazyka.</p>
    </item>
    <item>
      <p>Následující dva řádky omezí dialogové okno <gui>Open</gui>, aby zobrazovalo jen soubory, které lze otevřít pomocí <code>GtkImage</code>. Nejprve je vytvořen filtr a pak do něj přidáme všechny druhy souborů podporované v <link href="http://www.valadoc.org/gdk-pixbuf-2.0/Gdk.Pixbuf.html"><code>GdkPixbuf</code></link> (což zahrnuje většinu obrázkových formátů, včetně PNG a JPEG). Nakonec tento filtr nastavíme aby byl filtrem dialogového okna <gui>Open</gui>.</p>
    </item>
    <item>
      <p><link href="http://www.valadoc.org/gtk+-3.0/Gtk.Dialog.run.html"><code>dialog.run</code></link> zobrazí dialogové okno <gui>Open</gui>. Dialogové okno bude čekat na uživatele, než si vybere obrázek. Až tak učiní, vrátí <code>dialog.run</code> hodnotu <output>ResponseType.ACCEPT</output> typu <link href="http://www.valadoc.org/gtk+-3.0/Gtk.ResponseType.html">ResponseType</link> nebo by mohl vrátit <output>ResponseType.CANCEL</output>, když uživatel klikne na <gui>Cancel</gui>. Otestujeme to výrazem <code>switch</code>.</p>
    </item>
    <item>
      <p>Při předpokladu, že uživatel klikl na <gui>Open</gui>, následující řádek získá název souboru s obrázkem, který uživatel vybral a řekne widgetu <code>GtkImage</code>, aby jej načetl a zobrazil.</p>
    </item>
    <item>
      <p>Na posledním řádku této metody zlikvidujeme dialogové okno <gui>Open</gui>, protože jej již nebudeme potřebovat.</p>
      <p>Zlikvidováním se dialogové okno automaticky skryje.</p>
    </item>
  </list>
</section>

<section id="run">
  <title>Sestavení a spuštění aplikace</title>
  <p>Celý kód by nyní měl být připravený k fungování. Klikněte na <guiseq><gui>Sestavit</gui> <gui>Sestavit projekt</gui></guiseq>, aby se vše znovu sestavilo a pak na <guiseq><gui>Spustit</gui> <gui>Spustit</gui></guiseq>, aby se aplikace spustila.</p>
  <p>Pokud jste tak ještě neučinili, zvolte aplikaci <file>src/image-viewer</file> v dialogovém okně, které se objeví. Nakonec klikněte na <gui>Spustit</gui> a užijte si ji!</p>
</section>

<section id="impl">
  <title>Ukázková implementace</title>
  <p>Pokud v této lekci narazíte na nějaké problémy, porovnejte si svůj kód s tímto <link href="image-viewer/image-viewer.vala">ukázkovým kódem</link>.</p>
</section>

<section id="next">
  <title>Další postup</title>
  <p>Zde je pár nápadů, jak byste mohli tuto jednoduchou ukázku rozšířit:</p>
  <list>
  <item><p>Nastavit ji tak, že když se okno otevře, bude mít konkrétní počáteční velikost. Například 200 × 200 pixelů.</p></item>
   <item>
     <p>Umožnit uživateli výběr složky místo souboru a poskytnout ovládání pro procházení všech obrázků v této složce.</p>
   </item>
   <item>
     <p>Použít při načtení obrázku náhodné filtry a efekty a umožnit uživateli takto změněný obrázek uložit.</p>
     <p><link href="http://www.gegl.org/api.html">GEGL</link> poskytuje mocné schopnosti pro práci s obrázky.</p>
   </item>
   <item>
     <p>Umožnit uživateli načíst obrázky ze síťového sdílení, skenerů a dalších složitějších zdrojů.</p>
     <p>Pro práci se síťovými přenosy můžete použít <link href="http://library.gnome.org/devel/gio/unstable/">GIO</link> a pro obsluhu skeneru <link href="http://library.gnome.org/devel/gnome-scan/unstable/">GNOME Scan</link>.</p>
   </item>
  </list>
</section>

</page>