Přehled
Při návrhu layoutu, což je rozmístění prvků, si musíte okno rozdělit do jednotlivých sekcí a ty pak, v případě potřeby, do dalších sekcí. Nikde se nevyplňuje absolutní umístění. Pouze zadáváte, v které sekci, poté, co jste je dostatečně rozdělili, tento prvek má být. Jeho skutečné umístění udělá GTK sám a pokud to okolnosti vyžádají (změna obsahu a tím pádem velikosti prvků, uživatel si změnil téma vzhledu nebo velikost textu, roztažení/zmenšení okna apod.), sám prvky posune/přerovná tak, aby dodržely zamýšlený vzhled.
gtk.HBox()
Horizontální (vodorovný) box. Jakékoli prvky do něj umístíme budou řazeny vedle sebe vodorovně – od leva do prava.
gtk.VBox()
Vertikální (svislý) box. Jakékoli prvky do něj umístíme budou řazeny svisle – odshora dolů.
gtk.Table()
Tabulka. Pokud chcete mít několik prvků vyrovnané tak, jak jsou vyrovnaná políčka v tabulce, kombinace HBoxů a VBoxů není zrovna to nejlepší řešení. Vždy se vám budou rozcházet řádky nebo sloupce. Na to tu máme právě gtk.Table(). Ten nám umožní widgety řadit do tabulky a dá nám možnost vybrané widgety roztáhnout i přes několik políček, jak svisle, tak vodorovně.
gtk.Fixed()
Nedoporučovaný způsob. Zatímco u prvních tří určujete layout, zde jen absolutní umístění. Divím se, proč je tento nepružný způsob i se svými problémy na Windows tak hojně používán.
Stačí, abychom umístili nějaké prvky těsně vedle sebe a pak aplikaci předali někomu, kdo má vzhled systému trochu jiný, a překrývající se tlačítka či jiná selhání layoutu jsou na světě. Nebo si všimněte v druhém a prvním díle tohoto seriálu rozdílné velikosti tlačítek (a písma v nich) Linux/Windows. Zkrátka dokud nebude nejvyšší nouze vyhnutí, nepoužívejte to.
gtk.HBox() / gtk.VBox()
Popisovat budu pouze gtk.HBox(), protože screenshoty u něj vypadají lépe. Vše co si zde řekneme k HBoxu, platí i pro VBox. Metodicky jsou to naprosto stejné funkce, jen se liší směrem řazení prvků.
Vytvoření boxu
nas_hbox = gtk.HBox(homogeneous=False, spacing=0)
homogeneous – Všechny sekce mají mít stejnou velikost = velikost největší sekce.
spacing – Rozestup sekcí v pixelech.
Příklady:
Pro přehlednost mám nastavený rámeček na 10px ( okno.set_border_width(10)
).
nas_hbox = gtk.HBox()
Prvky mají velikost akorát, rozestup žádný.
nas_hbox = gtk.HBox(True, 5)
Prvky mají stejnou velikost – tlačítka jsou roztaženy na velikost editační linky, rozestup je 5px.
Balení prvků
nas_hbox.pack_start(child, expand=True, fill=True, padding=0)
nas_hbox.pack_end(child, expand=True, fill=True, padding=0)
pack_start/pack_end – Podle toho, zda chceme balit odleva/odshora = start, nebo odprava/odspodu = end.
child – Objekt, co chceme vložit, jediný povinný parametr.
expand – Zda se má sekce při roztažení HBoxu (pravděpodobně roztažení okna), roztahovat taktéž = True, nebo zůstat stejně velká = False.
fill – Vložený objekt má být roztažen přes celou sekci = True, má zůstat stejně velký a zvětšovat se budou pouze okraje = False.
padding – Okraje prvku (nevyplní tedy celou sekci) v pixelech.
Konflikty
– Pokud všechny prvky budou mít nastaveno expand = False, bude tato možnost vyrušena, protože není definováno, co se má při roztažení boxu roztáhnout = roztáhne se všechno.
– Pokud je v definici boxu homogeneous = True a některé sekce mají nastaveno expand = False, dostane přednost definice boxu a všechny prvky mají expand = True.
Příklady
Pro přehlednost mám nastavený rámeček na 10px ( okno.set_border_width(10)
).
Zakáz vyplnění:
nas_hbox = gtk.HBox(True, 5)
nas_hbox.pack_start(objekt, False, False)
Sekce jsou stejně velké (přednost definice boxu, expand=False neplatí), jejich velikost určila nejširší editační linka. Tlačítka ale již nejsou roztažená (fill=False).
Roztahování prvku:
nas_hbox = gtk.HBox(False, 5)
nas_hbox.pack_start(tlacitko3, True)
Pro tlačítko 3 jsem jako jediné zadal expand = True. Při vykreslení není nic vidět, ale po roztažení okna do šířky je vidět, že získaný prostor navíc získalo pouze a právě tlačítko 3.
gtk.Table()
Vytvoření tabulky
nase_tabulka = gtk.Table(rows=1, columns=1, homogeneous=False)
rows – Počet řádků.
columns – Počet sloupců.
homogeneus – Všechny políčka mají stejnou velikost, a to jak výšku, tak šířku = velikost největšího políčka.
Balení prvků
nase_tabulka.attach(child, left_attach, right_attach, top_attach, bottom_attach, xoptions=gtk.EXPAND|gtk.FILL, yoptions=gtk.EXPAND|gtk.FILL, xpadding=0, ypadding=0)
Při umísťování prvků se neoznačují čísla sloupců a řádků, ale čísla jejich oddělovacích linek. Ty se počítají z levého horního rohu od nuly. Více napoví následující obrázek.
child – Objekt, který chceme vložit.
left_attach – Číslo levé svislé čáry, které se bude dotýkat levý okraj námi vkládaného objektu.
right_attach – Číslo pravé svislé čáry, které se bude dotýkat pravý okraj námi vkládaného objektu. V případě, že objekt je jen v jednom políčku, je to left_attach+1.
top_attach – Číslo horní vodorovné čáry, které se bude dotýkat horní okraj námi vkládaného objektu.
bottom_attach – Číslo spodní vodorovné čáry, které se bude dotýkat spodní okraj námi vkládaného objektu. V případě, že objekt je jen v jednom políčku, je to top_attach+1.
xoptions / yoptions – Chování daného políčka tabulky při roztažení tabulky v ose x / y.
- gtk.EXPAND – roztahuje políčko, při změně velikosti tabulky
- gtk.FILL – roztahuje objekt, aby zabralo celý prostor políčka
- gtk.SHRINK – tak na jeho význam jsem bohužel nepřišel.
Pokud chcete použít více parametrů, oddělte jej znakem „|“ (horní znak klávesy „\“), na pořadí nezáleží.
xpadding – Velikost mezery vlevo a vpravo okolo objektu v pixelech.
ypadding – Velikost mezery nahoře a dole okolo objektu v pixelech.
A kde je sakra spacing?
Dobrá otázka. Zde je to trochu zbytečně komplikované. Na nastavení rozestupu musíme použít dvě metody tabulky, a to
tabulka.set_row_spacings(spacing) – Mezera mezi řádky tabulky v pixelech.
tabulka.set_col_spacings(spacing) – Mezera mezi sloupci tabulky v pixelech.
Konflikty
– Prvky sdílí stejné políčko (ať už přímo, nebo jej sdílejí svojí částí) – přednost ve vykreslení dostane dříve umístěný prvek.
– Čáry zadané při vkládání widgetu jsou mimo tabulku uvedenou v definici – tabulka se sama rozšíří, aby požadavek splnila.
Příklad
Pro přehlednost mám nastavený rámeček na 10px ( okno.set_border_width(10)
).
Tři tlačítka, dvě vedle sebe, třetí pod nimi, široké jako horní dvě dohromady. Rozestup mezi tlačítky je 5px.
#!/usr/bin/env python import gtk # Vytvoreni okna okno = gtk.Window() okno.set_border_width(10) okno.connect("destroy", gtk.main_quit) # Vytvoreni tlacitek tlacitko1 = gtk.Button("Tlacitko 1") tlacitko2 = gtk.Button("Tlacitko 2") tlacitko3 = gtk.Button("Tlacitko 3") # Vytvoreni a vyplneni tabulky tabulka = gtk.Table(2, 2, True) # 2 radky, 2 sloupce a stejna velikost policek tabulka.set_row_spacings(5) tabulka.set_col_spacings(5) tabulka.attach(tlacitko1, 0, 1, 0, 1) # prvni sloupec, prvni radek tabulka.attach(tlacitko2, 1, 2, 0, 1) # druhy sloupec, prvni radek tabulka.attach(tlacitko3, 0, 2, 1, 2) # prvni az druhy sloupec, druhy radek # start okno.add(tabulka) okno.show_all() gtk.main()
gtk.Fixed()
Vytvoření widgetu
nas_fixed = gtk.Fixed()
Balení prvků
nas_fixed.put(widget, x, y)
widget – Objekt, co chceme vložit.
x – X-ová souřadnice levého horního rohu.
y – Y-ová souřadnice levého horního rohu.
Fixed se počítá, stejně jako tabulka, od levého horního rohu od nuly. První pixel má souřadnice 0, 0.
Widgety lze přesouvat pomocí metody move(widget, x, y).
Příště:
Doteď to bylo hodně o teorii, ovšem od příště naskočíme konečně trochu na praxi.