Blame platform-demos/cs/image-viewer.c.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="image-viewer.c" xml:lang="cs">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <title type="text">Prohlížeč obrázků (C)</title>
Packit 1470ea
    <link type="guide" xref="c#examples"/>
Packit 1470ea
Packit 1470ea
    <desc>O trošku složitější aplikace Gtk než jednoduché „Hello world“.</desc>
Packit 1470ea
Packit 1470ea
    <revision pkgversion="0.1" version="0.1" date="2011-03-18" status="review"/>
Packit 1470ea
    <credit type="author">
Packit 1470ea
      <name>Dokumentační projekt GNOME</name>
Packit 1470ea
      <email its:translate="no">gnome-doc-list@gnome.org</email>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="author">
Packit 1470ea
      <name>Johannes Schmid</name>
Packit 1470ea
      <email its:translate="no">jhs@gnome.org</email>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="editor">
Packit 1470ea
      <name>Marta Maria Casetti</name>
Packit 1470ea
      <email its:translate="no">mmcasetti@gmail.com</email>
Packit 1470ea
      <years>2013</years>
Packit 1470ea
    </credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
<title>Prohlížeč obrázků</title>
Packit 1470ea
Packit 1470ea
<synopsis>
Packit 1470ea
  

V této lekci se seznámíme s následujícími věcmi:

Packit 1470ea
  <list>
Packit 1470ea
    <item>

Některými základními koncepty programování v C s GObject

</item>
Packit 1470ea
    <item>

Jak psát aplikaci Gtk v C

</item>
Packit 1470ea
  </list>
Packit 1470ea
</synopsis>
Packit 1470ea
Packit 1470ea
<media type="image" mime="image/png" src="media/image-viewer.png"/>
Packit 1470ea
Packit 1470ea
<section id="anjuta">
Packit 1470ea
  <title>Vytvoření projektu ve studiu Anjuta</title>
Packit 1470ea
  

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ě.

Packit 1470ea
  <steps>
Packit 1470ea
    <item>
Packit 1470ea
    

Spusťte IDE Anjuta a klikněte na <guiseq><gui>Soubor</gui> <gui>Nový</gui> <gui>Projekt</gui></guiseq>, aby se otevřel průvodce projektem.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Na kartě <gui>C</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>.

Packit 1470ea
   	</item>
Packit 1470ea
    <item>
Packit 1470ea
    

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ě. Jestli se chcete naučit, jak používat návrhář uživatelského rozhraní, podívejte se do lekce <link xref="guitar-tuner.c">Kytarová ladička</link>.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Klikněte na <gui>Použít</gui> a vytvoří se vám projekt. Otevřete <file>src/main.c</file> na kartě <gui>Projekt</gui> nebo <gui>Soubor</gui>. Měli byste vidět kód, který začíná řádky:

Packit 1470ea
    
Packit 1470ea
#include <config.h>
Packit 1470ea
#include <gtk/gtk.h>
Packit 1470ea
    </item>
Packit 1470ea
  </steps>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="build">
Packit 1470ea
  <title>Prvotní sestavení kódu</title>
Packit 1470ea
  

C je celkem „upovídaný“ jazyk, takže nebuďte překvapeni, že soubor obsahuje poměrně hodně kódu. Většina toho je kód šablony. Načte (prázdné) okno a zobrazí jej. Dále to podrobněji rozebereme. Pokud jste již pochopili základy, tak tento seznam můžete přeskočit:

Packit 1470ea
Packit 1470ea
  <list>
Packit 1470ea
  <item>
Packit 1470ea
    

Tři řádky #include na začátku vkládají knihovny config (užitečné definice pro sestavení pomocí autotools), gtk (uživatelské rozhraní) a gi18n (internacionalizace). Funkce z těchto knihoven se používají ve zbytku kódu.

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
    

Funkce create_window vytvoří nové (prázdné) okno a napojí signál, který zajistí ukončení aplikace, když je zavřeno okno.

Packit 1470ea
    

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 destroy (a ukončení aplikace) při zavření okna.

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
    

Funkce main se spustí jako výchozí, když spustíte aplikaci napsanou v jazyce C. Volá pár funkcí, které nastaví a spustí aplikaci. Funkce gtk_main spustí hlavní smyčku GTK, která spustí uživatelské rozhraní a začne naslouchat událostem (jako je kliknutí nebo zmáčknutí klávesy).

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
    

Podmíněná definice ENABLE_NLS nastavuje gettext, což je základní konstrukce pro překládání aplikací do národních jazyků. Tyto funkce určují, jak mají překladové nástroje pracovat s vaší aplikací za běhu.

Packit 1470ea
   </item>
Packit 1470ea
  </list>
Packit 1470ea
Packit 1470ea
  

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>).

Packit 1470ea
  

V následujícím okně zmáčkněte <gui>Spustit</gui>, aby se nakonfigurovalo ladicí sestavení. Stačí to udělat jen jednou, pro první sestavení.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="ui">
Packit 1470ea
<title>Vytvoření uživatelského rozhraní</title>
Packit 1470ea

Nyní prázdné okno oživíme. GTK uspořádává uživatelské rozhraní pomocí widgetů GtkContainer, které mohou obsahovat další widgety i další kontejnery. Zde použijeme nejjednodušší dostupný kontejner GtkBox:

Packit 1470ea
Packit 1470ea
static GtkWidget*
Packit 1470ea
create_window (void)
Packit 1470ea
{
Packit 1470ea
	GtkWidget *window;
Packit 1470ea
	GtkWidget *button;
Packit 1470ea
	GtkWidget *image;
Packit 1470ea
	GtkWidget *box;
Packit 1470ea
Packit 1470ea
	/* Vytvoří uživatelské rozhraní */
Packit 1470ea
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Packit 1470ea
	gtk_window_set_title (GTK_WINDOW (window), "image-viewer-c");
Packit 1470ea
Packit 1470ea
	box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
Packit 1470ea
	button = gtk_button_new_with_label (_("Open image"));
Packit 1470ea
	image = gtk_image_new ();
Packit 1470ea
Packit 1470ea
	gtk_box_pack_start (GTK_BOX (box), image, TRUE, TRUE, 0);
Packit 1470ea
	gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
Packit 1470ea
Packit 1470ea
	gtk_container_add (GTK_CONTAINER (window), box);
Packit 1470ea
Packit 1470ea
	/* Napojí signály */
Packit 1470ea
Packit 1470ea
	/* Při otevírání souboru zobrazí dialogové okno pro výběr souboru */
Packit 1470ea
	g_signal_connect (button, "clicked", G_CALLBACK (on_open_image), image);
Packit 1470ea
Packit 1470ea
	/* Skončit, když je zavřeno okno */
Packit 1470ea
	g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
Packit 1470ea
Packit 1470ea
	return window;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
  <steps>
Packit 1470ea
    <item>
Packit 1470ea
    

První řádek vytvoří widgety, které potřebujeme použít: tlačítko pro otevření obrázku, widget pro vlastní zobrazení obrázku a box, který použijeme jako kontejner. Makra, jako je GTK_BOX se používají pro dynamické typovou kontrolu a přetypování, což je potřeba, protože C nepodporuje samo o sobě objektově orientované programování.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Volání gtk_box_pack_start 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 jsme 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.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Potřebujeme nadefinovat, co se stane, když uživatel klikne na tlačítko. GTK používá koncept signálů. Když je kliknuto na tlačítko, spustí se signál clicked, který můžeme napojit na nějakou akci. To se udělá pomocí funkce g_signal_connect, která řekne GTK, aby zavolalo funkci on_image_open, když je na tlačítko kliknuto a předalo funkci obrázek jako dodatečný argument. Funkci zpětného volání nadefinujeme v další části.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Poslední g_signal_connect() zajistí, že se aplikace ukončí při zavření okna.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Jako poslední krok zajistěte nahrazení volání gtk_widget_show ve funkci main() za gtk_widget_show_all(), aby se zobrazilo okno a všechny widgety v něm.

Packit 1470ea
    </item>
Packit 1470ea
  </steps>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="image">
Packit 1470ea
<title>Zobrazení obrázku</title>
Packit 1470ea

Nyní nadefinujeme obsluhu signálu pro signál clicked tzn. pro tlačítko zmíněné dříve. Přidejte tento kód před metodu create_window().

Packit 1470ea
Packit 1470ea
static void
Packit 1470ea
on_open_image (GtkButton* button, gpointer user_data)
Packit 1470ea
{
Packit 1470ea
	GtkWidget *image = GTK_WIDGET (user_data);
Packit 1470ea
	GtkWidget *toplevel = gtk_widget_get_toplevel (image);
Packit 1470ea
	GtkFileFilter *filter = gtk_file_filter_new ();
Packit 1470ea
	GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Open image"),
Packit 1470ea
	                                                 GTK_WINDOW (toplevel),
Packit 1470ea
	                                                 GTK_FILE_CHOOSER_ACTION_OPEN,
Packit 1470ea
	                                                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
Packit 1470ea
	                                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
Packit 1470ea
	                                                 NULL);
Packit 1470ea
Packit 1470ea
	gtk_file_filter_add_pixbuf_formats (filter);
Packit 1470ea
	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog),
Packit 1470ea
	                             filter);
Packit 1470ea
Packit 1470ea
	switch (gtk_dialog_run (GTK_DIALOG (dialog)))
Packit 1470ea
	{
Packit 1470ea
		case GTK_RESPONSE_ACCEPT:
Packit 1470ea
		{
Packit 1470ea
			gchar *filename =
Packit 1470ea
				gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
Packit 1470ea
			gtk_image_set_from_file (GTK_IMAGE (image), filename);
Packit 1470ea
			break;
Packit 1470ea
		}
Packit 1470ea
		default:
Packit 1470ea
			break;
Packit 1470ea
	}
Packit 1470ea
	gtk_widget_destroy (dialog);
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
  

Toto je trochu komplikovanější než vše, o co jsme se doposud pokusili, takže si to pojďme rozebrat:

Packit 1470ea
  <list>
Packit 1470ea
    <item>

Prvním argumentem signálu 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 clicked žádný nemá. Další je argument user_data, což je ukazatel na data, která předáváme, když signál napojujeme. V tomto případě je to náš objekt GtkImage.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
      

Následující řádek, který stojí za pozornost, je ten, kde je pomocí gtk_file_chooser_dialog_new vytvořeno dialogové okno pro výběr souboru. Funkce přebírá název dialogového okna, rodičovské okno a několik voleb, jako je počet tlačítek a jim příslušející hodnoty.

Packit 1470ea
    

Všimněte si, že používáme standardní 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.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Následující dva řádky omezí dialogové okno <gui>Open</gui>, aby zobrazovalo jen soubory, které lze otevřít pomocí GtkImage. Nejprve je vytvořen filtr a pak do něj přidáme všechny druhy souborů podporované v GdkPixbuf (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>.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

gtk_dialog_run zobrazí dialogové okno <gui>Otevření</gui>. To bude čekat, až si uživatel vybere obrázek. Když to udělá, gtk_dialog_run vrátí hodnotu GTK_RESPONSE_ACCEPT (nebo by mohl vrátit GTK_RESPONSE_CANCEL, když uživatel klikne na <gui>Zrušit</gui>). V bloku switch se to otestuje.

Packit 1470ea
    </item>
Packit 1470ea
    <item>

Při předpokladu, že uživatel klikl na <gui>Open</gui>, následující řádek nastaví vlastnost file u GtkImage na název souboru s obrázkem, který uživatel vybral. GtkImage pak obrázek načte a zobrazí.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Na posledním řádku této metody zlikvidujeme dialogové okno <gui>Otevření</gui>, protože už jej nebudeme potřebovat. Tím se dialogové okno automaticky skryje.

Packit 1470ea
    </item>
Packit 1470ea
  </list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="run">
Packit 1470ea
  <title>Sestavení a spuštění aplikace</title>
Packit 1470ea
  

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.

Packit 1470ea
  

Pokud jste tak ještě neučinili, zvolte aplikaci <file>Debug/src/image-viewer</file> v dialogovém okně, které se objeví. Nakonec klikněte na <gui>Spustit</gui> a užijte si ji!

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="impl">
Packit 1470ea
 <title>Ukázková implementace</title>
Packit 1470ea
 

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.c">ukázkovým kódem</link>.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="next">
Packit 1470ea
  <title>Další postup</title>
Packit 1470ea
  

Zde je pár nápadů, jak byste mohli tuto jednoduchou ukázku rozšířit:

Packit 1470ea
  <list>
Packit 1470ea
   <item>
Packit 1470ea
   

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.

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
   

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.

Packit 1470ea
   

<link href="http://www.gegl.org/api.html">GEGL</link> poskytuje mocné schopnosti pro práci s obrázky.

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
   

Umožnit uživateli načíst obrázky ze síťového sdílení, skenerů a dalších složitějších zdrojů.

Packit 1470ea
   

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>.

Packit 1470ea
   </item>
Packit 1470ea
  </list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
Packit 1470ea
</page>