Hlavní navigace

Vzhled aplikací v PyGTK

Michal Smrž

Již třetí díl seriálu, který vás učí používat PyGTK. Dnes si ukážeme, jak lze řadit prvky do struktur a tím vytvářet layout - vzhled našich aplikací. Konkrétně bude řeč o gtk.HBox(), gtk.VBox(), gtk.Table() a okrajově škrtneme i o gtk.Fixed(). Vše doplněno screenshoty a ukázkou kódu u gtk.Table().

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(homo­geneous=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()

gtk Hbox

Prvky mají velikost akorát, rozestup žádný.

nas_hbox = gtk.HBox(True, 5)

gtk true5

Prvky mají stejnou velikost – tlačítka jsou roztaženy na velikost editační linky, rozestup je 5px.

Balení prvků
nas_hbox.pack_star­t(child, expand=True, fill=True, padding=0)
nas_hbox.pack_en­d(child, expand=True, fill=True, padding=0)

pack_start/pac­k_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)

gtk Hbox 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)

gtk Hbox 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=Fal­se)

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.at­tach(child, left_attach, right_attach, top_attach, bottom_attach, xoptions=gtk.EX­PAND|gtk.FILL, yoptions=gtk.EX­PAND|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.

Tabulka

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_spa­cings(spacing) – Mezera mezi řádky tabulky v pixelech.
tabulka.set_col_spa­cings(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()
Taulka1

gtk.Fixed()

Vytvoření widgetu
nas_fixed = gtk.Fixed()

Balení prvků
nas_fixed.put(wid­get, 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.

Našli jste v článku chybu?
Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

DigiZone.cz: Velká cena v Abú Dhabí: 131 ti­síc diváků

Velká cena v Abú Dhabí: 131 ti­síc diváků

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Měšec.cz: Stavební spoření: alternativa i pro seniory

Stavební spoření: alternativa i pro seniory

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

DigiZone.cz: ČRo rozšiřuje DAB do Berouna

ČRo rozšiřuje DAB do Berouna

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

120na80.cz: Na ucho teplý, nebo studený obklad?

Na ucho teplý, nebo studený obklad?

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky