This file is indexed.

/usr/share/help/cs/gnome-devel-demos/image-viewer.py.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.py" xml:lang="cs">

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

    <desc>O trošku složitější aplikace než jednoduché „Hello world“ – napíšeme prohlížeč obrázku v GTK.</desc>

    <revision pkgversion="0.1" version="0.1" date="2011-03-19" status="review"/>
    <credit type="author">
      <name>Jonh Wendell</name>
      <email its:translate="no">jwendell@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>
  </info>

<title>Prohlížeč obrázků</title>

<synopsis>
  <p>V této lekci napíšeme velmi jednoduchou aplikaci GTK, která načítá a zobrazuje soubory s obrázky. Naučíte se tyto věci:</p>
  <list>
    <item><p>Psát základní uživatelské rozhraní GTK v jazyce Python</p></item>
    <item><p>Zacházet s událostmi pomocí připojení signálu na obsluhu signálu.</p></item>
    <item><p>Rozvrhnout uživatelské rozhraní GTK pomocí kontejnerů.</p></item>
    <item><p>Načíst a zobrazit soubor s obrázkem.</p></item>
  </list>
  <p>Abyste mohli pokračovat v této lekci, budete potřebovat následující:</p>
  <list>
    <item><p>Nainstalovanou kopii <link xref="getting-ready">IDE Anjuta</link></p></item>
    <item><p>Základní znalosti programovacího jazyka Python</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 IDE Anjuta a klikněte na <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>Python</gui> zvolte <gui>PyGTK (automake)</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ě. Na příklad, jak používat návrhář uživatelského rozhraní, se podívejte do lekce <link xref="guitar-tuner.py">Kytarová ladička</link>.</p>
    </item>
    <item>
    <p>Klikněte na <gui>Použít</gui> a vytvoří se vám projekt. Otevřete <file>src/image_viewer.py</file> na kartě <gui>Projekt</gui> nebo <gui>Soubor</gui>. Obsahuje úplně základní kód příkladu.</p>
    </item>
  </steps>
</section>

<section id="first">
  <title>První aplikace Gtk</title>
  <p>Pojďme se podívat, jak by úplně základní aplikace Gtk mohl vypadat v jazyce Python:</p>
  <code mime="text/python" style="numbered">
from gi.repository import Gtk, GdkPixbuf, Gdk
import os, sys

class GUI:
	def __init__(self):
		window = Gtk.Window()
		window.set_title ("Hello World")
		window.connect_after('destroy', self.destroy)

		window.show_all()

	def destroy(window, self):
		Gtk.main_quit()

def main():
	app = GUI()
	Gtk.main()

if __name__ == "__main__":
    sys.exit(main())

  </code>
  <p>Podívejme se, co se stane:</p>
  <list>
    <item>
    <p>První řádek importuje jmenný prostor Gtk (tzn. vloží knihovnu Gtk). Knihovny jsou poskytovány pomocí GObject Introspection (gi), který poskytuje vazbu jazyka pro řadu knihoven GNOME.</p>
    </item>
    <item>
    <p>Metoda <code>__init__</code> třídy <code>GUI</code> vytvoří (prázdné) okno <code>Gtk.Window</code>, nastaví jeho název do záhlaví a napojí signál, aby se aplikace ukončila při zavření okna. Toto je celkem jednoduché a více si o signálech povíme později.</p>
    </item>
    <item>
    <p>Pak je definována funkce <code>destroy</code>, která akorát ukončí aplikaci. Je volána signálem <code>"destroy"</code> napojeným již dříve.</p>
    </item>
    <item>
    <p>Zbytek souboru provádí inicializaci pro Gtk a zobrazí GUI.</p>
    </item>
  </list>

  <p>Tento kód je připravený ke spuštění, takže zkuste použít <guiseq><gui>Spustit</gui> <gui>Spustit</gui></guiseq>. Mělo by se vám zobrazit prázdné okno.</p>
</section>

<section id="signals">
  <title>Signály</title>
  <p>Signály jsou klíčovým konceptem programování v Gtk. Kdykoliv se něco stane u nějakého objektu, tak onen objekt vyšle signál. Například, když je kliknuto na tlačítko, vyšle signál <code>"clicked"</code>. Pokud chcete, aby váš program něco udělal, když tato událost nastane, musíte napojit funkci („obsluhu signálu“) na tento signál. Zde je příklad:</p>
  <code mime="text/python" style="numbered">
def button_clicked () :
  print "you clicked me!"

b = new Gtk.Button ("Click me")
b.connect_after ('clicked', button_clicked)</code>
  <p>Poslední dva řádky vytvoří <code>Gtk.Button</code> nazvané <code>b</code> a napojí jeho signál <code>clicked</code> na funkci <code>button_clicked</code>, která byla definována dříve. Pokaždé, když je kliknuto na tlačítko, provede se kód ve funkci <code>button_clicked</code>. Ten akorát vypíše zprávu.</p>
</section>

<section id="containers">
  <title>Kontejnery: Rozvržení uživatelského rozhraní</title>
  <p>Widgety (ovládací prvky, jako jsou tlačítka a popisky) lze v okně uspořádat pomocí <em>kontejnerů</em>. Můžete dohromady kombinovat různé kontejnery, jako jsou boxy nebo mřížky.</p>
  <p><code>Gtk.Window</code> je samo o sobě kontejner, ale přímo do něj můžete vložit jen jeden widget. My bychom měli rádi dva widgety, obrázek a tlačítko, takže musíme do okna vložit „vysokokapacitní“ kontejner, pro tyto další widgety. Je dostupná řada <link href="http://library.gnome.org/devel/gtk/stable/GtkContainer.html">typů kontejnerů</link>, ale my zde použijeme <code>Gtk.Box</code>. Ten může obsahovat několik widgetů uspořádaných vodorovně nebo svisle. Složitější rozvržení můžete udělat vložením několika boxů do jiného boxu atd.</p>
  <note>
  <p>Existuje návrhář grafického uživatelského rozhraní nazývaný <app>Glade</app>, který je zaintegrován i do IDE <app>Anjuta</app>. S ním můžete navrhovat uživatelské rozhraní opravdu snadno. V tomto příkladu ale vše napíšeme ručně.</p>
  </note>
  <p>Pojďme přidat box a widgety do okna. Vložte následující kód do metody <code>__init__</code>, hned za řádek <code>window.connect_after</code>:</p>
<code mime="text/python" style="numbered">
box = Gtk.Box()
box.set_spacing (5)
box.set_orientation (Gtk.Orientation.VERTICAL)
window.add (box)

</code>
  <p>První řádek vytvoří <code>Gtk.Box</code> nazvaný <code>box</code> a následující řádky nastaví dvě jeho vlastnosti: <code>orientation</code> (otočení) je nastavena na svislou (takže widgety jsou uspořádány do sloupce) a <code>spacing</code> (rozestupy) mezi widgety jsou nastaveny na 5 pixelů. Následující řádek pak přidá nově vytvořený <code>Gtk.Box</code> do okna.</p>
  <p>Zatím okno obsahuje jen prázdný <code>Gtk.Box</code> a pokud spustíte program nyní, neuvidíte oproti dřívějšku žádné změny (<code>Gtk.Box</code> je průhledný kontejner, takže jej tam nemůžete vidět).</p>
</section>

<section id="packing">
  <title>Balení: Přidání widgetů do kontejneru</title>
  <p>Pro přidání nějakého widgetu do <code>Gtk.Box</code> vložte následující kód hned za řádek <code>window.add (box)</code>:</p>
  <code mime="text/python" style="numbered">
self.image = Gtk.Image()
box.pack_start (self.image, False, False, 0)</code>
  <p>První řádek vytvoří nový <code>Gtk.Image</code> nazvaný <code>image</code>, který bude zobrazovat soubor s obrázkem. Protože jej budeme později potřebovat v obsluze signálu, nadefinujeme jej jako proměnou třídy. Musíte přidat <code>image = 0</code> na začátek třídy <code>GUI</code>. Po té je widget obrázku přidán (<em>zabalen</em>) do kontejneru <code>box</code> pomocí metody <link href="http://library.gnome.org/devel/gtk/stable/GtkBox.html#gtk-box-pack-start"><code>pack_start</code></link> widgetu <code>GtkBox</code>.</p>
  <p><code>pack_start</code> přebírá 4 argumenty: widget, který je přidáván do <code>Gtk.Box</code> (<code>child</code>); zda by se měl <code>Gtk.Box</code> zvětšit, když je přidán nový widget (<code>expand</code>); zda by měl nový widget zabrat všechno vytvořené dodatečné místo, když je <code>Gtk.Box</code> větší (<code>fill</code>); jak moc místa, v pixelech, by mělo být mezi widgetem a jeho sousedem uvnitř <code>Gtk.Box</code> (<code>padding</code>).</p>
  <p>Kontejnery Gtk (a widgety) se dynamicky roztahují, aby zaplnily dostupné místo, pokud jim to tedy dovolíte. Neumisťujte widgety zadáváním přesných souřadnic x,y v okně. Místo toho je umisťujte relativně vůči sobě. To umožní oknu, které se o ně stará, jednodušeji měnit velikost a widgety by tak měli dostat automaticky rozumnou velikost ve většině situací.</p>
  <p>Všimněte si také, jak jsou widgety uspořádány do hierarchie. Jakmile jsou zabaleny v <code>Gtk.Box</code>, je <code>Gtk.Image</code> považován za potomka <em>Gtk.Box</em>. To umožňuje zacházet se všemi potomky widgetu jako se skupinou. Například byste mohli skrýt <code>Gtk.Box</code>, což by zároveň skrylo i všechny jeho potomky.</p>
  <p>Nyní vložte tyto dva řádky pod ty dva, které jsme již přidali:</p>
  <code mime="text/python" style="numbered">
button = Gtk.Button ("Open a picture...")
box.pack_start (button, False, False, 0)
</code>
  <p>Tyto řádky jsou podobné jako první dva, ale tentokrát vytváří <code>Gtk.Button</code> a přidávají ho do widgetu <code>box</code>. Všimněte si, že zde nastavujeme argument <code>expand</code> (ten druhý) na <code>False</code>, zatímco pro <code>Gtk.Image</code> byl nastaven na <code>True</code>. To způsobí, že obrázek zabere všechno dostupné místo a tlačítko jen tolik místa, kolik potřebuje. Když okno maximalizujete, zůstane velikost tlačítka stejná, ale obrázek se zvětší, aby zabral celý zbytek okna.</p>
</section>

<section id="loading">
  <title>Načtení obrázku: Napojení signálu <code>clicked</code> od tlačítka</title>
  <p>Když uživatel klikne na tlačítko <gui>Open Image…</gui>, mělo by se objevit dialogové okno, ve kterém si uživatel může vybrat obrázek. Až jej má vybraný, měl by se obrázek načíst a zobrazit ve widgetu obrázku.</p>
  <p>Prvním krokem je napojit signál <code>clicked</code> od tlačítka na obslužnou funkci signálu, kterou jsem nazvali <code>on_open_clicked</code>. Vložte tento kód hned za řádek <code>button = Gtk.Button()</code>, kde bylo tlačítko vytvořeno:</p>
  <code mime="text/python">
button.connect_after('clicked', self.on_open_clicked)
</code>
  <p>Tímto se připojí signál <code>clicked</code> k metodě <code>on_open_clicked</code>, která bude definována níže.</p>
</section>

<section id="loading2">
  <title>Načítání obrázku: Psaní zpětných volání pro signály</title>
  <p>Nyní vytvoříme metodu <code>on_open_clicked</code>. Vložte následující do bloku s kódem třídy <code>GUI</code> za metodu <code>__init__</code>:</p>
    <code mime="text/javascript" style="numbered">
def on_open_clicked (self, button):
	dialog = Gtk.FileChooserDialog ("Open Image", button.get_toplevel(), Gtk.FileChooserAction.OPEN);
	dialog.add_button (Gtk.STOCK_CANCEL, 0)
	dialog.add_button (Gtk.STOCK_OK, 1)
	dialog.set_default_response(1)

	filefilter = Gtk.FileFilter ()
	filefilter.add_pixbuf_formats ()
	dialog.set_filter(filefilter)

	if dialog.run() == 1:
		self.image.set_from_file(dialog.get_filename())

	dialog.destroy()</code>
  <p>Toto je trochu komplikovanější než vše, o co jsme se doposud pokusili, takže si to pojďme rozebrat:</p>
  <list>
    <item>
      <p>Řádek začínající <code>dialog</code> vytvoří dialogové okno <gui>Open</gui>, které může uživatel použít k výběru souboru. Nastavíme tři vlastnosti: název dialogového okna; akci (typ) dialogového okna (jde o dialogové okno <gui>Open</gui>, ale mohli bychom použít <code>SAVE</code>, pokud by záměrem bylo uložení souboru; <code>transient_for</code>, která nastaví rodičovské okno dialogového okna.</p>
    </item>
    <item>
    <p>Následující dva řádky přidají do dialogového okna tlačítka <gui>Cancel</gui> a <gui>Open</gui>. Druhým argumentem metody <code>add_button</code> je celočíselná hodnota, která bude vrácena při zmáčknutí tlačítka: 0 pro <gui>Cancel</gui> a 1 pro <gui>Open</gui>.</p>
    <p>Všimněte si, že používáme <em>standardní</em> 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><code>set_default_response</code> určuje tlačítko, které bude aktivováno, když uživatel dvojitě klikne na soubor nebo zmáčkne <key>Enter</key>. V našem případě používáme jako výchozí tlačítko <gui>Open</gui> (které má hodnotu 1).</p>
    </item>
    <item>
    <p>Následující tři řádky omezí dialogové okno <gui>Open</gui>, aby zobrazovalo jen soubory, které lze otevřít pomocí <code>Gtk.Image</code>. Nejprve je vytvořen filtr a pak do něj přidáme všechny druhy souborů podporované v <code>Gdk.Pixbuf</code> (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><code>dialog.run</code> zobrazí dialogové okno <gui>Open</gui>. Dialogové okno bude čekat na uživatele, než si vybere nějaký nějaký obrázek. Až tak učiní, vrátí <code>dialog.run</code> hodnotu <output>1</output> nebo by mohl vrátit <output>0</output>, když uživatel klikne na <gui>Cancel</gui>. Otestujeme to výrazem <code>if</code>.</p>
    </item>
    <item><p>Předpokládejme, že uživatel klikl na <gui>Open</gui>. Následující řádek nastaví vlastnost <code>file</code> v <code>Gtk.Image</code> na název souboru s obrázkem, který si uživatel vybral. <code>Gtk.Image</code> vybraný obrázek načte a zobrazí.</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>
    </item>
  </list>

  </section>

<section id="run">
  <title>Spuštění aplikace</title>
  <p>Všechen kód, který potřebujete, je nyní nachystaný, takže jej můžete zkusit spustit. Tím jste během krátké chvíle získali, co jsme slíbili – plně funkční prohlížeč obrázků (a tím končí naše cesta jazykem Python a knihovnou Gtk).</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.py">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>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>