Blame platform-demos/cs/image-viewer.cpp.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.cpp" xml:lang="cs">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <link type="guide" xref="cpp#examples"/>
Packit 1470ea
Packit 1470ea
    <desc>O trošku složitější aplikace GTKmm 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é základní koncepty programování s C++/GObject

</item>
Packit 1470ea
    <item>

Jak psát aplikace Gtk v jazyce 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>GTKmm (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.cpp">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.cc</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 <gtkmm.h>
Packit 1470ea
#include <iostream>
Packit 1470ea
Packit 1470ea
#include "config.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
  

Jedná se o zcela základní kód C++ nastavující GTKmm. Podrobněji je to popsáno dále. Pokud základům rozumíte, tak tento sezmam přeskočte:

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), gtkmm (uživatelské rozhraní) a iostream (C++-STL). Funkce z těchto knihoven se používají ve zbytku kódu.

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

Funkce main vytvoří nové (prázdné) okno a nastaví název do jeho záhlaví.

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

Funkce kit::run() spustí hlavní smyčku GTKmm, která spustí uživatelské rozhraní a začne naslouchat událostem (jako jsou kliknutí nebo zmáčknutí kláves). Protože jsme této funkci jako argument předali okno, ukončí se aplikace automaticky při zavření tohoto okna.

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í oživíme prázdné okno. GTKmm uspořádává uživatelské rozhraní pomocí kontejneru Gtk::Container, který může obsahovat další widgety a také další kontejnery. Zde použijeme nejjednodušší dostupný kontejner Gtk::Box:

Packit 1470ea
Packit 1470ea
int
Packit 1470ea
main (int argc, char *argv[])
Packit 1470ea
{
Packit 1470ea
	Gtk::Main kit(argc, argv);
Packit 1470ea
Packit 1470ea
	Gtk::Window main_win;
Packit 1470ea
	main_win.set_title ("image-viewer-cpp");
Packit 1470ea
Packit 1470ea
	Gtk::Box* box = Gtk::manage(new Gtk::Box());
Packit 1470ea
	box->set_orientation (Gtk::ORIENTATION_VERTICAL);
Packit 1470ea
	box->set_spacing(6);
Packit 1470ea
	main_win.add(*box);
Packit 1470ea
Packit 1470ea
	image = Gtk::manage(new Gtk::Image());
Packit 1470ea
	box->pack_start (*image, true, true);
Packit 1470ea
Packit 1470ea
	Gtk::Button* button = Gtk::manage(new Gtk::Button("Open Image…"));
Packit 1470ea
	button->signal_clicked().connect (
Packit 1470ea
		sigc::ptr_fun(&on_open_image));
Packit 1470ea
	box->pack_start (*button, false, false);
Packit 1470ea
Packit 1470ea
	main_win.show_all_children();
Packit 1470ea
	kit.run(main_win);
Packit 1470ea
Packit 1470ea
	return 0;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
  <steps>
Packit 1470ea
    <item>
Packit 1470ea
    

První řádky vytvoří widgety, které chceme používat: tlačítko pro otevření obrázku, vlastní widget pro zobrazení obrázku a box,, který použijeme jako kontejner.

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

Volání 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 jsem u widgetů výslovně nenastavili velikost. GTKmm 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. GTKmm 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 signal_clicked().connect, která řekne GTKmm, aby zavolalo funkci on_open_image, když je na tlačítko kliknuto. Funkci zpětného volání nadefinujeme v další části.

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

Posledním krokem je zobrazit všechny widgety v okně pomocí show_all_children(). Je to stejné, jako byste zavolali metodu show() postupně u všech našich synovských widgetů.

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

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

Packit 1470ea
Packit 1470ea
Gtk::Image* image = 0;
Packit 1470ea
Packit 1470ea
static void
Packit 1470ea
on_open_image ()
Packit 1470ea
{
Packit 1470ea
	Gtk::FileChooserDialog dialog("Open image",
Packit 1470ea
	                              Gtk::FILE_CHOOSER_ACTION_OPEN);
Packit 1470ea
	dialog.add_button (Gtk::Stock::OPEN,
Packit 1470ea
	                   Gtk::RESPONSE_ACCEPT);
Packit 1470ea
	dialog.add_button (Gtk::Stock::CANCEL,
Packit 1470ea
	                   Gtk::RESPONSE_CANCEL);
Packit 1470ea
Packit 1470ea
	Glib::RefPtr<Gtk::FileFilter> filter =
Packit 1470ea
		Gtk::FileFilter::create();
Packit 1470ea
	filter->add_pixbuf_formats();
Packit 1470ea
	filter->set_name("Images");
Packit 1470ea
	dialog.add_filter (filter);
Packit 1470ea
Packit 1470ea
	const int response = dialog.run();
Packit 1470ea
	dialog.hide();
Packit 1470ea
Packit 1470ea
	switch (response)
Packit 1470ea
	{
Packit 1470ea
		case Gtk::RESPONSE_ACCEPT:
Packit 1470ea
			image->set(dialog.get_filename());
Packit 1470ea
			break;
Packit 1470ea
		default:
Packit 1470ea
			break;
Packit 1470ea
	}
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>
Packit 1470ea
      

Dialogové okno pro výběr souboru je vytvořeno pomocí konstruktoru Gtk::FileChooserDialog. Jako argumenty přebírá název a typ dialogového okna. V našem případě je to dialogové okno Open.

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

Následující dva řádky přidají do dialogového okna tlačítka Open a Close.

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
    

Druhým argumentem metody add_button() je hodnota identifikující kliknuté tlačítko. I zde použijeme předdefinované hodnoty poskytované GTKmm.

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í Gtk::Image. Nejprve je vytvořen filtr a pak do něj přidáme všechny druhy souborů podporované v Gdk::Pixbuf (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
    

Glib::RefPtr je chytrý ukazatel, který zde použijeme, aby se zajistilo, že filtr bude zlikvidován, až na něj nepovede žádný odkaz.

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

dialog.run zobrazí dialogové okno <gui>Open</gui>. Dialogové okno bude čekat na uživatele, než si vybere obrázek. Až tak učiní, vrátí dialog.run hodnotu <output>Gtk::RESPONSE_ACCEPT</output> nebo by mohl vrátit <output>Gtk::RESPONSE_CANCEL</output>, když uživatel klikne na <gui>Cancel</gui>. Otestujeme to výrazem switch.

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

Skryjeme dialogové okno <gui>Open</gui>, protože jej již nebudeme potřebovat. Stejně by mohl být skryt později, protože jde jen o místní proměnnou a bude zlikvidována (a tím dialogové okno skryto), až se dorazí na konec rozsahu působnosti.

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

Při předpokladu, že uživatel klikl na <gui>Open</gui>, následující řádky načtou soubor do Gtk::Image, takže se zobrazí.

Packit 1470ea
    </item>
Packit 1470ea
  </list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="build2">
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.cc">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>