Tvorba grafického uživatelského rozhraní v Pythonu s využitím knihovny Kivy: kontejnery

Včera
Doba čtení: 35 minut

Sdílet

Autor: Root.cz s využitím DALL-E
Budeme se zabývat velmi důležitými prvky, na kterých je tvorba uživatelského rozhraní postavena. Jedná se o takzvané kontejnery (containers), které se někdy nazývají správci geometrie (geometry managers).

Obsah

1. Tvorba grafického uživatelského rozhraní v Pythonu s využitím knihovny Kivy: kontejnery

2. Kontejner grid layout

3. Specifikace šířky okrajů okolo widgetů umístěných do mřížky

4. Modifikace velikosti widgetů umístěných do mřížky

5. Výchozí šířka nebo výška widgetů

6. Kontejner stack layout

7. Nastavení výšky widgetů umístěných do kontejneru typu stack

8. Různé kombinace výšky a šířky widgetů v okně s pevně zadanými rozměry

9. Specifikace pořadí vkládání widgetů do kontejneru

10. Kontejner box layout

11. Vertikální orientace kontejneru box

12. Složitější UI formulářů a dialogů: kombinace většího množství kontejnerů

13. Kontejner box, do kterého jsou vloženy další kontejnery box

14. Popis UI formulářů a dialogů v jazyce Kv

15. Definice dialogu postaveného na kontejneru typu grid

16. Definice dialogu postaveného na kontejneru typu stack

17. Definice dialogu, který využívá kontejnery typu box uvnitř jiného kontejneru stejného typu

18. Další typy kontejnerů poskytovaných knihovnou Kivy

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Tvorba grafického uživatelského rozhraní v Pythonu s využitím knihovny Kivy: kontejnery

Ve třetím článku o tvorbě grafického uživatelského rozhraní v programovacím jazyce Python s využitím knihovny Kivy se budeme zabývat velmi důležitými prvky, na kterých je tvorba uživatelského rozhraní postavena. Jedná se o takzvané kontejnery (containers), které se někdy nazývají správci geometrie (geometry managers) v závislosti na použité UI knihovně nebo frameworku. V tomto článku budeme používat termín „kontejner“.

Připomeňme si, že samotné ovládací prvky (widgety) nejsou na obrazovce (resp. na ploše desktopu) prakticky nikdy zcela osamocené; ostatně většina knihoven pro GUI by samostatný widget ani nedokázala zobrazit. Ve skutečnosti se ovládací prvky téměř vždy nachází v nějakém okně, dialogu či dalším nadřazeném widgetu. Programátoři grafických uživatelských rozhraní se často setkají s pojmem kontejner. Jedná se o komponentu, na kterou lze vkládat různé widgety a mnohdy i další kontejnery.

Obecně tak interně vzniká stromová datová struktura jejíž kořen je představován plochou na obrazovce, na které jsou umístěna okna aplikací (dnes je ovšem i samotná plocha obrazovky součástí větší virtuální plochy zobrazované obecně na více monitorech). V těchto oknech se dále nachází kontejnery a widgety. V mnoha grafických uživatelských rozhraních přitom mohou být vybrané widgety (zdaleka ne však všechny) současně i kontejnery. Kontejnery kromě jiného řeší i rozmístění widgetů na své ploše.

Poznámka: stromová struktura kontejnerů a widgetů nemusí být na první pohled zřejmá v případě, že se grafické uživatelské rozhraní tvoří přímo ve zdrojovém kódu (zde konkrétně v Pythonu). Ovšem pokud pro popis GUI použijeme jazyk Kv, stane se tato struktura zcela zřejmá.

Dnes se seznámíme s trojicí základních kontejnerů, jejichž znalost postačuje pro tvorbu prakticky všech běžných formulářů a dialogů. Jedná se o:

  1. Grid layout (umístění komponent do pomyslné mřížky)
  2. Stack layout (komponenty jsou umístěny za sebou nebo pod sebou s tím, že dokážou „přetéct“ na další řádky)
  3. Box layout (komponenty jsou umístěny buď vedle sebe nebo pod sebe, ovšem nedokážou automaticky „přetéct“ tak, jako v případě předchozího kontejneru).
Poznámka: prakticky vždy se setkáme s kombinací většího množství kontejnerů, ať již stejného, či odlišného typu. Typicky bývají kontejnery umisťovány do jiných kontejnerů s tím, že konkrétní rozmístění ovládacích prvků je do jisté míry určeno velikostí okna atd. Díky tomu lze vytvořit uživatelské rozhraní použitelné jak na desktopu, tak i například na (obecně menší) ploše dotykového displeje.

2. Kontejner grid layout

S kontejnerem nazvaným grid layout jsme se již seznámili, protože byl použit v demonstračních příkladech představených v prvním i ve druhém článku o knihovně Kivy. Připomeňme si, že plocha tohoto kontejneru je rozdělena pomyslnou pravidelnou mřížkou na buňky, do kterých se vkládají jednotlivé ovládací prvky a/nebo jiné kontejnery. Šířka sloupců tabulky popř. výška jejích řádků je odvozena od velikosti widgetů, která je konfigurovatelná. Počet sloupců je nastaven při konstrukci kontejneru, zatímco počet řádků je odvozen od počtu vložených widgetů.

V dnešním prvním demonstračním příkladu vytvoříme mřížku se třemi sloupci (a předem neznámým počtem řádků):

layout = GridLayout(cols=3)

Dále do kontejneru vložíme celkem devět tlačítek, takže vznikne mřížka se třemi řádky:

button = Button(text="1")
layout.add_widget(button)
...
...
...
button = Button(text="9")
layout.add_widget(button)

Při velikosti okna 200×200 délkových jednotek bude výsledné uživatelské rozhraní vypadat takto:

Obrázek 1: Devět tlačítek rozmístěných pomocí kontejneru grid.

Obrázek 1: Devět tlačítek rozmístěných pomocí kontejneru „grid“.

Autor: tisnik, podle licence: Rights Managed

Následuje úplný zdrojový kód dnešního prvního demonstračního příkladu:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = GridLayout(cols=3)
 
        button = Button(text="1")
        layout.add_widget(button)
 
        button = Button(text="2")
        layout.add_widget(button)
 
        button = Button(text="3")
        layout.add_widget(button)
 
        button = Button(text="4")
        layout.add_widget(button)
 
        button = Button(text="5")
        layout.add_widget(button)
 
        button = Button(text="6")
        layout.add_widget(button)
 
        button = Button(text="7")
        layout.add_widget(button)
 
        button = Button(text="8")
        layout.add_widget(button)
 
        button = Button(text="9")
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

Programátoři, co nesnášíte BS, ale máte rádi business! Y Soft je česká firma s globálním dopadem (100+ zemí, 1M+ uživatelů a >100% meziroční růst). R&D úplně bez manažerů (130 developerů). Otevíráme 30 pozic pro Cloud a AI: Praha/Brno/Ostrava/remote. Zodpovědnost ano, mikro-management ne. Pojď někam, kde můžeš věci změnit.

Y Soft logo

3. Specifikace šířky okrajů okolo widgetů umístěných do mřížky

Vlastnosti mřížky, do které se vkládají jednotlivé ovládací prvky, lze do jisté míry ovládat. Prozatím jsme pouze specifikovali počet sloupců tabulky:

layout = GridLayout(cols=3)

V případě potřeby je ovšem možné specifikovat okraje okolo ovládacích prvků i okolo celé mřížky:

layout = GridLayout(cols=3, padding=10, spacing=10)

Výsledkem bude dialog, který bude vypadat následovně:

Obrázek 2: Komponenty se specifikovanou šířkou rozmístěné pomocí kontejneru typu grid

Obrázek 2: Komponenty se specifikovanou šířkou rozmístěné pomocí kontejneru typu „grid“.

Autor: tisnik, podle licence: Rights Managed

Hodnoty padding a spacing jsou na sobě nezávislé, takže je možné navrhnout například i tyto dialogy:

Obrázek 3: Nastavení hodnoty padding zatímco hodnota spacing je nulová.

Obrázek 3: Nastavení hodnoty padding zatímco hodnota spacing je nulová.

Autor: tisnik, podle licence: Rights Managed
Obrázek 4: Nastavení hodnoty spacing zatímco hodnota padding je nulová.

Obrázek 4: Nastavení hodnoty spacing zatímco hodnota padding je nulová.

Autor: tisnik, podle licence: Rights Managed

Opět si pochopitelně ukážeme celý zdrojový kód takto upraveného demonstračního příkladu:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = GridLayout(cols=3, padding=10, spacing=10)
 
        button = Button(text="1")
        layout.add_widget(button)
 
        button = Button(text="2")
        layout.add_widget(button)
 
        button = Button(text="3")
        layout.add_widget(button)
 
        button = Button(text="4")
        layout.add_widget(button)
 
        button = Button(text="5")
        layout.add_widget(button)
 
        button = Button(text="6")
        layout.add_widget(button)
 
        button = Button(text="7")
        layout.add_widget(button)
 
        button = Button(text="8")
        layout.add_widget(button)
 
        button = Button(text="9")
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

4. Modifikace velikosti widgetů umístěných do mřížky

Velikost ovládacích prvků vkládaných do mřížky kontejneru typu grid je možné do určité míry ovlivnit. Při konstrukci většiny widgetů se může zapsat jejich výchozí velikost, tj. šířka a/nebo výška. Pokud nechceme, aby se výpočet velikosti prováděl automaticky, je navíc ještě vhodné nastavit parametr size_hint_x nebo size_hint_y na hodnotu None (a to opět při konstrukci widgetu). Podívejme se na příklad, ve kterém změníme šířku všech tlačítek umístěných do prvního sloupce mřížky:

button = Button(text="1", size_hint_x=None, width=30)
...
...
...
button = Button(text="4", size_hint_x=None, width=30)
...
...
...
button = Button(text="7", size_hint_x=None, width=30)
Poznámka: každé tlačítko pochopitelně může mít odlišnou velikost.

Výsledek může vypadat následovně (ovšem vizuální podoba se změní ve chvíli, kdy zmenšíme nebo zvětšíme okno s dialogem):

Obrázek 5: Kontejner grid layout s různě širokými sloupci

Obrázek 5: Kontejner grid layout s různě širokými sloupci.

Autor: tisnik, podle licence: Rights Managed

Úplný zdrojový kód demonstračního příkladu, ve kterém je do dialogu vloženo devět tlačítek, přičemž tlačítka v prvním sloupci mají odlišnou šířku třiceti délkových jednotek, vypadá následovně:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = GridLayout(cols=3, padding=10, spacing=10)
 
        button = Button(text="1", size_hint_x=None, width=30)
        layout.add_widget(button)
 
        button = Button(text="2")
        layout.add_widget(button)
 
        button = Button(text="3")
        layout.add_widget(button)
 
        button = Button(text="4", size_hint_x=None, width=30)
        layout.add_widget(button)
 
        button = Button(text="5")
        layout.add_widget(button)
 
        button = Button(text="6")
        layout.add_widget(button)
 
        button = Button(text="7", size_hint_x=None, width=30)
        layout.add_widget(button)
 
        button = Button(text="8")
        layout.add_widget(button)
 
        button = Button(text="9")
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

5. Výchozí šířka nebo výška widgetů

Výchozí velikost widgetů je možné (i když nepřímo) ovlivnit velikostí buněk pomyslné mřížky, do které se ovládací prvky vkládají. Můžeme si například vynutit nastavení výšky buněk, a to do značné míry nezávisle na tom, jakou velikost ovládacích prvků (například tlačítek) vypočítá knihovna Kivy. Příkladem je nastavení (a vynucení) výšky buněk mřížky na čtyřicet délkových jednotek, což je provedeno přímo při konstrukci kontejneru typu grid layout:

layout = GridLayout(
    cols=3,
    padding=10,
    spacing=10,
    row_force_default=True,
    row_default_height=40,
)

Povšimněte si, že v tomto případě nebudou tři řádky mřížky nataženy přes celou výšku okna (přesněji řečeno přes výšku, od které se dvakrát odečte deset délkových jednotek rezervovaných pro okraje):

Obrázek 6: Kontejner grid layout s různě širokými sloupci a explicitně nastavenou výškou řádků

Obrázek 6: Kontejner grid layout s různě širokými sloupci a explicitně nastavenou výškou řádků.

Autor: tisnik, podle licence: Rights Managed

Upravený zdrojový kód demonstračního příkladu bude nyní vypadat takto:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = GridLayout(
            cols=3,
            padding=10,
            spacing=10,
            row_force_default=True,
            row_default_height=40,
        )
 
        button = Button(text="1", size_hint_x=None, width=30)
        layout.add_widget(button)
 
        button = Button(text="2")
        layout.add_widget(button)
 
        button = Button(text="3")
        layout.add_widget(button)
 
        button = Button(text="4", size_hint_x=None, width=30)
        layout.add_widget(button)
 
        button = Button(text="5")
        layout.add_widget(button)
 
        button = Button(text="6")
        layout.add_widget(button)
 
        button = Button(text="7", size_hint_x=None, width=30)
        layout.add_widget(button)
 
        button = Button(text="8")
        layout.add_widget(button)
 
        button = Button(text="9")
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

6. Kontejner stack layout

Druhým typem kontejneru, se kterým se v dnešním článku setkáme, je kontejner nazvaný stack layout. Jedná se o poměrně unikátní kontejner, který v mnoha dalších knihovnách pro tvorbu grafického uživatelského rozhraní nenajdeme. Tento typ kontejneru umožňuje jednotlivé komponenty vkládat za sebe (naprosto stejným způsobem, jako znaky v textu) nebo pod sebe. Ovšem pokud se daná komponenta již na aktuální „řádek“ nevejde (přesahuje plochu kontejneru), je automaticky přesunuta na další pomyslný „řádek“. Pokud se tedy komponenty (ovládací prvky nebo vložené kontejnery) vkládají vedle sebe, je chování skutečně do značné míry podobné automatickému zalamování textu do odstavce.

Díky tomu je kontejner stack layout možné s výhodou použít v těch aplikacích, které mají být provozovány jak na desktopech (kde je typicky k dispozici velká volná plocha), tak i na smartphonech (obecně menší volná plocha a tedy potřeba „zalamování“, zejména při orientaci displeje na výšku).

Podívejme se nyní na základní způsob použití tohoto kontejneru. Do plochy dialogu opět vložíme devět tlačítek, u kterých budeme specifikovat jejich požadovanou (relativní) výšku, zatímco šířka bude dopočítána automaticky knihovnou Kivy. Tlačítka budou vkládána za sebe, ovšem pokud by se měla překročit dostupná plocha okna, bude další tlačítko „zalomeno“ na další pomyslný řádek:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.stacklayout import StackLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = StackLayout()
 
        button = Button(text="1", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="2", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="3", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="4", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="5", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="6", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="7", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="8", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        button = Button(text="9", size_hint=(None, 0.15))
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

Ihned po spuštění tohoto demonstračního příkladu by mělo okno s dialogem vypadat takto – komponenty byly rozmístěny tak, že po vložení dvojice tlačítek došlo k „odřádkování“:

Obrázek 7: Automatické rozmístění tlačítek ve výchozím stavu, kdy je okno široké 200 délkových jednotek

Obrázek 7: Automatické rozmístění tlačítek ve výchozím stavu, kdy je okno široké 200 délkových jednotek.

Autor: tisnik, podle licence: Rights Managed

Ovšem ve chvíli, kdy změníme velikost okna, dojde i k automatickému přemístění komponent, které jsou do kontejneru umístěny:

Obrázek 8: Odlišné rozmístění komponent po změně velikosti okna

Obrázek 8: Odlišné rozmístění komponent po změně velikosti okna.

Autor: tisnik, podle licence: Rights Managed

7. Nastavení výšky widgetů umístěných do kontejneru typu stack

Nepovinným parametrem nazvaným size_hint, který se předává do konstruktoru při tvorbě ovládacích prvků, je možné specifikovat očekávanou šířku a/nebo výšku tohoto prvku. Kvůli tvorbě programů s grafickým uživatelským rozhraním, které mají být přenositelné na různé platformy, mohou být tyto rozměry specifikovány relativně vůči ploše, kterou celý kontejner zabírá. Pokud například nastavíme výšku na hodnotu 1/5, bude se knihovna Kivy snažit o to, aby výška komponenty dosahovala právě 1/5 (tedy 20%) výšky kontejneru (a v případě, že je kontejner umístěn přímo do plochy okna, tak se jedná o 1/5, resp. 20% jeho výšky):

button = Button(text="1", size_hint=(None, 1/5))
layout.add_widget(button)
Poznámka: nastavit by bylo možné i relativní šířku tlačítka. V takovém případě by došlo k tomu, že se tlačítko bude rozšiřovat nebo zužovat společně se změnou velikosti okna.

Požadovaná výška widgetu se uplatní po přidání widgetů do kontejneru typu stack následovně:

Obrázek 9: Výška tlačítek odpovídá jedné pětině výšky okna

Obrázek 9: Výška tlačítek odpovídá jedné pětině výšky okna.

Autor: tisnik, podle licence: Rights Managed

Výška tlačítek zůstane zachována i tehdy, pokud se změní velikost okna a dojde k přeuspořádání komponent:

POPISEK

Obrázek 10:

Autor: tisnik, podle licence: Rights Managed

Opět si pochopitelně ukážeme úplný zdrojový kód tohoto demonstračního příkladu:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.stacklayout import StackLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = StackLayout()
 
        button = Button(text="1", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="2", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="3", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="4", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="5", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="6", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="7", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="8", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        button = Button(text="9", size_hint=(None, 1/5))
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

8. Různé kombinace výšky a šířky widgetů v okně s pevně zadanými rozměry

Nyní si ukážeme, jakým způsobem lze dosáhnout toho, aby byla tlačítka v dialogu umístěna stejným způsobem, jak je to patrné ze screenshotu:

Obrázek 11: Devět tlačítek s nastavenými rozměry (šířka a výška).

Obrázek 11: Devět tlačítek s nastavenými rozměry (šířka a výška).

Autor: tisnik, podle licence: Rights Managed

U všech tlačítek nastavíme relativní šířku a výšku vztaženou k celé ploše kontejneru. Například tlačítko, které má být stejně široké, jako kontejner, ovšem jeho výška má být pětinová, se zkonstruuje takto:

button = Button(text="1", size_hint=(1/1, 1/5))
...
...
...

Naopak, pokud budeme chtít, aby se dvě tlačítka umístila vedle sebe, musí být jejich relativní šířka rovna 1/2:

button = Button(text="2", size_hint=(1/2, 1/5))
...
...
...
button = Button(text="3", size_hint=(1/2, 1/5))
...
...
...
Poznámka: díky tomu, že je šířka a výška nastavena relativně k ploše kontejneru, nebude mít změna velikosti okna vliv na rozmístění tlačítek (to zůstane zachováno), ovšem pochopitelně dojde ke změně jejich velikosti.

Následuje výpis úplného zdrojového kódu tohoto demonstračního příkladu, ve kterém je do kontejneru přidáno všech devět tlačítek:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.stacklayout import StackLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = StackLayout()
 
        button = Button(text="1", size_hint=(1/1, 1/5))
        layout.add_widget(button)
 
        button = Button(text="2", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="3", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="4", size_hint=(1/3, 1/5))
        layout.add_widget(button)
 
        button = Button(text="5", size_hint=(1/3, 1/5))
        layout.add_widget(button)
 
        button = Button(text="6", size_hint=(1/3, 1/5))
        layout.add_widget(button)
 
        button = Button(text="7", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="8", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="9", size_hint=(1/1, 1/5))
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

Dialog ve chvíli, kdy je jedno z tlačítek stisknuto:

Obrázek 12: Vizuální obsah dialogu v okamžiku, kdy je jedno z tlačítek stisknuto

Obrázek 12: Vizuální obsah dialogu v okamžiku, kdy je jedno z tlačítek stisknuto.

Autor: tisnik, podle licence: Rights Managed

9. Specifikace pořadí vkládání widgetů do kontejneru

Parametrem orientation předávaným do konstruktoru kontejneru lze zvolit, v jakém pořadí budou widgety (či další kontejnery) vkládány do volné plochy. Hodnota tohoto parametru se předává v řetězci:

Hodnota Pořadí vkládání
„lr-tb“ left-right, top-bottom (výchozí hodnota)
„tb-lr“ top-bottom, left-right
„rl-tb“ right-left, top-bottom (zrcadlení okolo vertikální osy)
„tb-rl“ top-bottom, right-left
„lr-bt“ left-right, bottom-top
„bt-lr“ bottom-top, left-right
„rl-bt“ right-left, bottom-top
„bt-rl“ bottom-top, right-left

Prakticky má (alespoň podle mého názoru) význam volit jen mezi hodnotami „lr-tb“ a „rl-tb“. Ostatně vyzkoušejme si, jak bude vypadat dialog, pokud si vyžádáme vkládání komponent v pořadí zprava-doleva a potom shora dolů. Až na hodnotu orientation se tento příklad nijak neliší od příkladu předchozího:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.stacklayout import StackLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = StackLayout(orientation="rl-tb")
 
        button = Button(text="1", size_hint=(1/1, 1/5))
        layout.add_widget(button)
 
        button = Button(text="2", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="3", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="4", size_hint=(1/3, 1/5))
        layout.add_widget(button)
 
        button = Button(text="5", size_hint=(1/3, 1/5))
        layout.add_widget(button)
 
        button = Button(text="6", size_hint=(1/3, 1/5))
        layout.add_widget(button)
 
        button = Button(text="7", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="8", size_hint=(1/2, 1/5))
        layout.add_widget(button)
 
        button = Button(text="9", size_hint=(1/1, 1/5))
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

Výsledkem bude dialog, ve kterém jsou tlačítka vertikálně zrcadlena (ovšem ne jejich obsah, pouze umístění v ploše kontejneru):

Obrázek 13: Dialog, ve kterém je zvolena orientace widgetů lr-tb

Obrázek 13: Dialog, ve kterém je zvolena orientace widgetů lr-tb.

Autor: tisnik, podle licence: Rights Managed

10. Kontejner box layout

Třetím typem kontejneru, který si dnes popíšeme, je kontejner nazvaný box layout. Při použití tohoto kontejneru jsou jednotlivé ovládací prvky (widgety) nebo další kontejnery umístěny buď vedle sebe nebo pod sebou (orientace je zvolena při jeho konstrukci). Ovšem na rozdíl od kontejneru stack layout zde nedochází k automatickému „zalamování“ komponent na další řádky. Z tohoto pohledu je tedy box layout jedním z nejjednodušších kontejnerů. A jeho jednoduchost je současně i jeho největší předností, protože se tento kontejner typicky velmi snadno kombinuje s dalšími kontejnery (stejného či odlišného typu), což umožňuje tvorbu relativně složitých dialogů a formulářů.

Nejprve si ukažme, jakým způsobem se tento kontejner chová v případě, že při jeho konstrukci neuvedeme žádné další parametry, tedy jaké je jeho výchozí chování:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = BoxLayout()
 
        button = Button(text="1")
        layout.add_widget(button)
 
        button = Button(text="2")
        layout.add_widget(button)
 
        button = Button(text="3")
        layout.add_widget(button)
 
        button = Button(text="4")
        layout.add_widget(button)
 
        button = Button(text="5")
        layout.add_widget(button)
 
        button = Button(text="6")
        layout.add_widget(button)
 
        button = Button(text="7")
        layout.add_widget(button)
 
        button = Button(text="8")
        layout.add_widget(button)
 
        button = Button(text="9")
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (400, 400)
 
 
if __name__ == "__main__":
    Application().run()

Do kontejneru bylo přidáno devět tlačítek, která byla umístěna vedle sebe. Kontejner navíc vyplnil celou plochu okna, takže se tlačítka příslušně zvýšila:

Obrázek 14: Rozmístění devíti tlačítek na plochu kontejneru typu box layout

Obrázek 14: Rozmístění devíti tlačítek na plochu kontejneru typu box layout.

Autor: tisnik, podle licence: Rights Managed
Poznámka: otestujte si, jak se bude okno chovat v případě, že ho zvětšíte nebo zmenšíte. Kontejner typu box layout bude na tuto situaci korektně reagovat.

11. Vertikální orientace kontejneru box

Jak jsme si již řekli v předchozí kapitole, umožňuje kontejner typu box layout umístění komponent vedle sebe nebo pod sebe. Ve výchozím stavu se komponenty umisťují vedle sebe v pořadí zleva doprava, ovšem parametrem orientation předávaným konstruktoru kontejneru lze zajistit vertikální orientaci, tj. umisťování komponent v pořadí shora dolů:

layout = BoxLayout(orientation="vertical")

Výsledný dialog s devíti tlačítky bude nyní vypadat takto:

Obrázek 15: Rozmístění devíti tlačítek na plochu kontejneru typu box layout, použita je vertikální orientace komponent

Obrázek 15: Rozmístění devíti tlačítek na plochu kontejneru typu box layout, použita je vertikální orientace komponent.

Autor: tisnik, podle licence: Rights Managed

Pro úplnost je uveden i celý zdrojový kód takto upraveného demonstračního příkladu:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = BoxLayout(orientation="vertical")
 
        button = Button(text="1")
        layout.add_widget(button)
 
        button = Button(text="2")
        layout.add_widget(button)
 
        button = Button(text="3")
        layout.add_widget(button)
 
        button = Button(text="4")
        layout.add_widget(button)
 
        button = Button(text="5")
        layout.add_widget(button)
 
        button = Button(text="6")
        layout.add_widget(button)
 
        button = Button(text="7")
        layout.add_widget(button)
 
        button = Button(text="8")
        layout.add_widget(button)
 
        button = Button(text="9")
        layout.add_widget(button)
 
        return layout
 
    def on_start(self):
        Window.size = (400, 400)
 
 
if __name__ == "__main__":
    Application().run()

12. Složitější UI formulářů a dialogů: kombinace většího množství kontejnerů

Na první pohled by se mohlo zdát, že kontejner typu box layout vlastně nabízí při tvorbě grafického uživatelského rozhraní jen omezené možnosti. To je do jisté míry pravda, ovšem jeho největší předností je snadná kombinace s dalšími kontejnery. GUI ze screenshotu číslo 16 můžeme například realizovat následujícím způsobem:

  1. Do plochy okna je vložen kontejner typu box layout nastavený tak, že komponenty budou umístěny pod sebou (orientation=„vertical“).
  2. První komponentou bude další kontejner typu box layout s výchozím nastavením. Do tohoto „podkontejneru“ vložíme tři tlačítka.
  3. Druhou komponentou bude další kontejner typu box layout s výchozím nastavením. Nyní do tohoto „podkontejneru“ vložíme tlačítka čtyři.
  4. Třetí komponentou bude další kontejner typu box layout s výchozím nastavením, do něhož jsou vložena dvě tlačítka.

Výsledkem bude okno s devíti tlačítky rozmístěnými následujícím způsobem:

Obrázek 16: GUI postavené na hierarchii kontejnerů typu box layout

Obrázek 16: GUI postavené na hierarchii kontejnerů typu box layout.

Autor: tisnik, podle licence: Rights Managed

Samozřejmě můžeme nastavit i parametry padding a spacing. Pokud oba parametry nastavíme na deset délkových jednotek (u hlavního kontejneru), bude celá struktura GUI mnohem více patrná:

Obrázek 17: Změna parametrů padding a spacing u hlavního kontejneru

Obrázek 17: Změna parametrů padding a spacing u hlavního kontejneru.

Autor: tisnik, podle licence: Rights Managed

13. Kontejner box, do kterého jsou vloženy další kontejnery box

Ukažme si nyní prakticky, jakým způsobem lze programově vytvořit dialogy ze screenshotů 16 a 17 uvedené v předchozí kapitole. Nejprve vytvoříme „hlavní“ kontejner:

layout = BoxLayout(orientation="vertical")

Dále do tohoto kontejneru vložíme tři další kontejnery:

first_panel = BoxLayout(orientation="horizontal")
layout.add_widget(first_panel)
 
second_panel = BoxLayout(orientation="horizontal")
layout.add_widget(second_panel)
 
third_panel = BoxLayout(orientation="horizontal")
layout.add_widget(third_panel)

Nyní do každého z těchto kontejnerů můžeme libovolně vkládat jednotlivé widgety, například:

button = Button(text="1")
first_panel.add_widget(button)
 
button = Button(text="9")
third_panel.add_widget(button)
...
...
...

Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = BoxLayout(orientation="vertical")
 
        first_panel = BoxLayout(orientation="horizontal")
        button = Button(text="1")
        first_panel.add_widget(button)
 
        button = Button(text="2")
        first_panel.add_widget(button)
 
        button = Button(text="3")
        first_panel.add_widget(button)
 
        layout.add_widget(first_panel)
 
        second_panel = BoxLayout(orientation="horizontal")
        button = Button(text="4")
        second_panel.add_widget(button)
 
        button = Button(text="5")
        second_panel.add_widget(button)
 
        button = Button(text="6")
        second_panel.add_widget(button)
 
        button = Button(text="7")
        second_panel.add_widget(button)
 
        layout.add_widget(second_panel)
 
        third_panel = BoxLayout(orientation="horizontal")
        button = Button(text="8")
        third_panel.add_widget(button)
 
        button = Button(text="9")
        third_panel.add_widget(button)
 
        layout.add_widget(third_panel)
 
        return layout
 
    def on_start(self):
        Window.size = (400, 300)
 
 
if __name__ == "__main__":
    Application().run()

Samozřejmě nic nebrání v tom, aby se okolo jednotlivých „podkontejnerů“ vytvořily okraje:

layout = BoxLayout(orientation="vertical", padding=20, spacing=20)

Tím vznikne dialog, který jsme mohli vidět na screenshotu číslo 17:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
 
 
class Application(App):
    def build(self):
        layout = BoxLayout(orientation="vertical", padding=20, spacing=20)
 
        first_panel = BoxLayout(orientation="horizontal")
        button = Button(text="1")
        first_panel.add_widget(button)
 
        button = Button(text="2")
        first_panel.add_widget(button)
 
        button = Button(text="3")
        first_panel.add_widget(button)
 
        layout.add_widget(first_panel)
 
        second_panel = BoxLayout(orientation="horizontal")
        button = Button(text="4")
        second_panel.add_widget(button)
 
        button = Button(text="5")
        second_panel.add_widget(button)
 
        button = Button(text="6")
        second_panel.add_widget(button)
 
        button = Button(text="7")
        second_panel.add_widget(button)
 
        layout.add_widget(second_panel)
 
        third_panel = BoxLayout(orientation="horizontal")
        button = Button(text="8")
        third_panel.add_widget(button)
 
        button = Button(text="9")
        third_panel.add_widget(button)
 
        layout.add_widget(third_panel)
 
        return layout
 
    def on_start(self):
        Window.size = (400, 300)
 
 
if __name__ == "__main__":
    Application().run()

14. Popis UI formulářů a dialogů v jazyce Kv

V úvodním článku o knihovně Kivy jsme si řekli, že grafické uživatelské rozhraní (tj. jednotlivé dialogy a formuláře) je možné vytvořit dvěma různými způsoby. Buď explicitně v Pythonu konstrukcí jednotlivých kontejnerů a programovým vkládáním widgetů do těchto kontejnerů, nebo lze uživatelské rozhraní plně popsat v jazyku Kv. Samotný kód v Pythonu může být minimální, protože pouze potřebujeme načíst příslušné popisy uživatelského rozhraní a popř. naprogramovat reakce na události. Díky existenci jazyka Kv lze popis uživatelského rozhraní zcela oddělit od programové logiky, což přináší větší čitelnost zdrojových kódů aplikace. Navíc je možné vytvářet například interaktivní editory grafického uživatelského rozhraní, které budou pracovat pouze s jazykem Kv (což je do značné míry podobný koncept, jaký používalo Delphi nebo Visual Baisc) atd. V dalších třech kapitolách si ukážeme způsob popisu formulářů založených na všech třech výše popsaných kontejnerech, tj. na grid layout, stack layoutbox layout.

15. Definice dialogu postaveného na kontejneru typu grid

V první ukázce definice dialogu v jazyku Kv použijeme kontejner typu grid, do kterého jsou vkládány další komponenty. Povšimněte si, jakým způsobem jsou definovány parametry kontejneru (tj. zejména hodnoty cols, padding a spacing) i toho, že kontejner společně s tlačítky skutečně tvoří stromovou strukturu. U všech tlačítek je definován jejich popisek (text) a u trojice tlačítek v prvním sloupci i jejich očekávaná šířka:

GridLayout:
    id: grid_layout
    padding: 10
    spacing: 10
    cols:3
    Button:
        text: "1"
        size_hint_x: None
        width: 30
    Button:
        text: "2"
    Button:
        text: "3"
    Button:
        text: "4"
        size_hint_x: None
        width: 30
    Button:
        text: "5"
    Button:
        text: "6"
    Button:
        text: "7"
        size_hint_x: None
        width: 30
    Button:
        text: "8"
    Button:
        text: "9"

Skript napsaný v Pythonu, který po svém spuštění načte definici dialogu a následně ho zobrazí, vypadá následovně:

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
 
 
class Application(App):
    def build(self):
        builder = Builder.load_file("grid_layout.kv")
        return builder
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

Dialog, který je zobrazen po spuštění tohoto demonstračního příkladu, by měl vypadat takto:

Obrázek 18: Devět tlačítek v kontejneru typu grid s mřížkou 3×3 buňky

Obrázek 18: Devět tlačítek v kontejneru typu grid s mřížkou 3×3 buňky.

Autor: tisnik, podle licence: Rights Managed

16. Definice dialogu postaveného na kontejneru typu stack

Následuje výpis obsahu souboru, který obsahuje popis dialogu založeného na kontejneru typu stack. Nastaveny jsou nulové šířky okrajů okolo okna i nulové mezery mezi jednotlivými ovládacími prvky. Následně je na kontejner vloženo celkem devět tlačítek s explicitně nastavenou relativní šířkou a relativní výškou. Povšimněte si, že je možné používat zlomky, z čehož je alespoň náznakem patrné, že Kv je opravdu spíše jazykem, nežli konfiguračním formátem:

StackLayout:
    id: stack_layout
    padding: 0
    spacing: 0
    Button:
        text: "1"
        size_hint: [1, 1/5]
    Button:
        text: "2"
        size_hint: [1/2, 1/5]
    Button:
        text: "3"
        size_hint: [1/2, 1/5]
    Button:
        text: "4"
        size_hint: [1/3, 1/5]
    Button:
        text: "5"
        size_hint: [1/3, 1/5]
    Button:
        text: "6"
        size_hint: [1/3, 1/5]
    Button:
        text: "7"
        size_hint: [1/2, 1/5]
    Button:
        text: "8"
        size_hint: [1/2, 1/5]
    Button:
        text: "9"
        size_hint: [1, 1/5]

Skript, který výše uvedenou definici dialogu načte a dialog zobrazí, vypadá takto:

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
 
 
class Application(App):
    def build(self):
        builder = Builder.load_file("stack_layout.kv")
        return builder
 
    def on_start(self):
        Window.size = (200, 200)
 
 
if __name__ == "__main__":
    Application().run()

Výsledkem je okno, které by mělo vypadat následovně:

Obrázek 19:

Obrázek 19: Devět tlačítek s různou šířkou vložených do kontejneru typu stack.

Autor: tisnik, podle licence: Rights Managed
Poznámka: nyní se pokuste o změnu šířky okna a sledujte, jakým způsobem se tlačítka přeskládají.

17. Definice dialogu, který využívá kontejnery typu box uvnitř jiného kontejneru stejného typu

V dnešním posledním demonstračním příkladu je ukázáno, jakým způsobem se v jazyku Kv popíše dialog založený na kontejneru typu box, do kterého jsou vloženy další tři kontejnery stejného typu (tyto kontejnery jsou uspořádány vertikálně, tedy pod sebou). A do těchto tří kontejnerů jsou vloženy ovládací prvky – tlačítka. Tato tlačítka jsou uspořádána horizontálně, tedy vedle sebe a v každém kontejneru je jich odlišný počet:

BoxLayout:
    id: box_layout
    orientation: "vertical"
 
    BoxLayout:
        orientation: "horizontal"
        Button:
            text: "1"
        Button:
            text: "2"
        Button:
            text: "3"
 
    BoxLayout:
        orientation: "horizontal"
        Button:
            text: "4"
        Button:
            text: "5"
        Button:
            text: "6"
        Button:
            text: "7"
 
    BoxLayout:
        orientation: "horizontal"
        Button:
            text: "8"
        Button:
            text: "9"

Skript, který výše takto zapsanou dialogu načte a dialog následně zobrazí, vypadá takto:

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
 
 
class Application(App):
    def build(self):
        builder = Builder.load_file("box_layout.kv")
        return builder
 
    def on_start(self):
        Window.size = (400, 300)
 
 
if __name__ == "__main__":
    Application().run()

Výsledkem bude tento dialog zobrazený na ploše desktopu:

Školení Hacking

Obrázek 20: Trojice kontejnerů typu

Obrázek 20: Trojice kontejnerů typu „box“ umístěných do jiného kontejneru stejného typu.

Autor: tisnik, podle licence: Rights Managed

18. Další typy kontejnerů poskytovaných knihovnou Kivy

Kromě třech výše popsaných kontejnerů jsou v knihovně Kivy dostupné i další typy kontejnerů:

  1. AnchorLayout umožňuje umístění až pěti komponent (či dalších kontejnerů) do pěti oblastí, na které je plocha rozdělena (nahoře, dole, vlevo, vpravo, uprostřed). Obdobu tohoto kontejneru nalezneme i v dalších knihovnách určených pro tvorbu GUI.
  2. FloatLayout umožňuje „volné“ pozicování jednotlivých komponent na dostupné ploše. To vlastně znamená, že výpočet souřadnic komponent je ponechán na programu (a tedy i na vývojáři).
  3. RelativeLayout slouží, jak již jeho název naznačuje, pro pozicování jednotlivých komponent na dostupné ploše. Na rozdíl od předchozího kontejneru jsou souřadnice určeny relativně vůči dalším komponentám a nikoli absolutně. Změna pozice jedné komponenty pak vede i k posunu dalších komponent.
  4. PageLayout je velmi zajímavý kontejner, který umožňuje na ploše okna zobrazit více „virtuálních“ ploch (s widgety nebo i dalšími kontejnery), přičemž je možné se interaktivně mezi jednotlivými plochami přepínat posunem jejich okrajů (swiping).
  5. ScatterLayout se do značné míry podobá kontejneru RelativeLayout. Rozdíly mezi těmito dvěma kontejnery si popíšeme v navazujícím článku.

19. Repositář s demonstračními příklady

Demonstrační příklady, s nimiž jsme se dnes seznámili a které jsou určeny pro Python 3.11 (a libovolnou vyšší verzi Pythonu) a knihovnu Kivy, jsou dostupné, jak je zvykem, na GitHubu. V tabulce níže jsou uvedeny odkazy na jednotlivé zdrojové kódy i na definice formulářů:

# Příklad Stručný popis Adresa
1 pyproject.toml projektový soubor pro všechny demonstrační příklady založené na knihovně Kivy https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/pyproject.toml
       
2 hello_world.py aplikace tvořená jediným oknem s nápisem https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/hello_world.py
3 hello_world2.py specifikace základních vlastností okna aplikace https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/hello_wor­ld2.py
       
4 hello_kv_spec.py načtení GUI popsané v jazyku Kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/hello_kv_spec.py
5 TestApp.kv popis GUI v jazyku Kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/TestApp.kv
       
6 hello_kv_spec2.py načtení GUI popsané v jazyku Kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/hello_kv_spec.py
7 TestApp2.kv změna stylů textových návěští v jazyku Kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/TestApp2.kv
       
8 hello_kv_spec3.py načtení GUI popsané v jazyku Kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/hello_kv_spec.py
9 TestApp3.kv další ukázka modifikace stylu vykreslování https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/TestApp3.kv
       
10 login_form1.py dialog pro přihlášení (login) do aplikace https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form1.py
11 login_form2.py specifikace velikosti okna s přihlašovacím dialogem https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form2.py
12 login_form3.py konfigurace vlastností kontejneru (padding a spacing) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form3.py
13 login_form4.py reakce na událost typu on start https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form4.py
       
14 login_form5.py inicializace přihlašovacího dialogu z Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form5.py
15 login_form5.kv popis GUI přihlašovacího dialogu v jazyku Kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form5.kv
16 login_form6.kv https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/login_form6.py
       
17 widget_basic1.py základní ovládací prvky: textové návěští a tlačítko, reakce na stisk tlačítka https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_basic1.py
18 widget_basic2.py základní ovládací prvky: textové návěští a tlačítko, reakce na uvolnění tlačítka https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_basic2.py
       
19 widget_toggle_button.py tlačítko se dvěma stavy (ToggleButton) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_toggle_button.py
20 widget_checkbox.py zaškrtávací pole (Checkbox) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_checkbox.py
21 widget_checkbox2.py zaškrtávací pole (Checkbox) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_checkbox2.py
22 widget_checkbox3.py zaškrtávací pole (Checkbox), změna šířky sloupců mřížky https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_checkbox3.py
23 widget_radio_buttons1.py přepínač vytvořený ze zašrtávacích polí (nekorektní varianta) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_radio_buttons1.py
24 widget_radio_buttons2.py přepínač vytvořený ze zašrtávacích polí (korektní varianta) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/wid­get_radio_buttons2.py
25 widget_slider.py posuvník (Slider) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/widget_slider.py
26 widget_colors.py definice barev ovládacích prvků https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/widget_colors.py
27 widget_icon.py změna ikony ovládacích prvků https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/widget_icon.py
       
28 widget_rgb.py nastavení barvy widgetu na základě stavu posuvníků (horizontální orientace posuvníků) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/widget_rgb.py
29 widget_rgb2.py nastavení barvy widgetu na základě stavu posuvníků (vertikální orientace posuvníků) https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/widget_rgb2.py
       
30 grid_layout1.py kontejner typu grid layout, přidání devíti tlačítek na plochu dialogu https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/grid_la­yout1.py
31 grid_layout2.py specifikace šířky okrajů okolo widgetů umístěných do mřížky https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/grid_la­yout2.py
32 grid_layout3.py modifikace velikosti widgetů umístěných do mřížky https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/grid_la­yout3.py
33 grid_layout4.py výchozí šířka nebo výška widgetů https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/grid_la­yout4.py
34 grid_layout5.py načtení a použití dialogu popsaného v jazyce Kv a používajícího grid layout https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/grid_la­yout5.py
35 grid_layout.kv definice dialogu postaveného na kontejneru typu grid https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/grid_layout.kv
       
36 stack_layout1.py kontejner typu stack layout, přidání devíti tlačítek na plochu dialogu https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/stac­k_layout1.py
37 stack_layout2.py nastavení výšky widgetů umístěných do kontejneru typu stack https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/stac­k_layout2.py
38 stack_layout3.py různé kombinace výšky a šířky widgetů v okně s pevně zadanými rozměry https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/stac­k_layout3.py
39 stack_layout4.py specifikace pořadí vkládání widgetů do kontejneru https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/stac­k_layout4.py
40 stack_layout5.py načtení a použití dialogu popsaného v jazyce Kv a používajícího stack layout https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/stac­k_layout5.py
41 stack_layout.kv definice dialogu postaveného na kontejneru typu stack https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/stack_layout.kv
       
42 box_layout1.py kontejner typu box layout, přidání devíti tlačítek na plochu dialogu https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/box_layout1.py
43 box_layout2.py vertikální orientace kontejneru box https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/box_layout2.py
44 box_layout3.py kontejner box, do kterého jsou vloženy další kontejnery box https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/box_layout3.py
45 box_layout4.py načtení a použití dialogu popsaného v jazyce Kv a používajícího box layout https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/box_layout4.py
46 box_layout.kv definice dialogu, který využívá kontejnery typu box uvnitř jiného kontejneru stejného typu https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/box_layout.kv
47 box_layout5.py použití modifikátorů padding a spacing https://github.com/tisnik/most-popular-python-libs/blob/master/kivy/box_layout5.py

20. Odkazy na Internetu

  1. Welcome to KivyMD’s documentation!
    https://kivymd.readthedoc­s.io/en/latest/
  2. Kivy Tutorial
    https://www.geeksforgeeks­.org/python/kivy-tutorial/
  3. Stránky projektu Kivy
    https://kivy.org/#home
  4. Two Ways To Change Background Colors – Python Kivy GUI Tutorial
    https://kivycoder.com/two-ways-to-change-background-colors-python-kivy-gui-tutorial-11/
  5. 5 Best Ways to Adjust Window Size in Kivy with Python
    https://blog.finxter.com/5-best-ways-to-adjust-window-size-in-kivy-with-python/
  6. Python | Make a simple window using kivy
    https://www.geeksforgeeks­.org/python/python-make-a-simple-window-using-kivy/
  7. Python | Ellipse (different polygons) in Kivy
    https://www.geeksforgeeks­.org/python/python-ellipse-different-polygons-in-kivy/
  8. Getting Started » Kv Design Language
    https://kivy.org/doc/stable/get­tingstarted/rules.html
  9. Python | Kivy .kv File
    https://www.geeksforgeeks­.org/python/python-kivy-kv-file/
  10. Kivy na GitHubu
    https://github.com/kivy/kivy
  11. PySimpleGUI
    https://www.pysimplegui.or­g/en/latest/
  12. DearPyGui na GitHubu
    https://github.com/hoffstad­t/DearPyGui
  13. PySimpleGUI Tutorial
    https://www.tutorialspoin­t.com/pysimplegui/index.htm
  14. PySimpleGUI – Canvas Element
    https://www.tutorialspoin­t.com/pysimplegui/pysimple­gui_canvas_element.htm
  15. Dokumentace ke knihovně PySimpleGUI
    https://www.pysimplegui.or­g/en/latest/
  16. Dokumentace ke knihovně DearPyGui
    https://dearpygui.readthe­docs.io/en/latest/index.html#
  17. The Hitchhiker's Guide to Pyhton: GUI Applications
    http://docs.python-guide.org/en/latest/scenarios/gui/
  18. 7 Top Python GUI Frameworks for 2017
    http://insights.dice.com/2014/11/26/5-top-python-guis-for-2015/
  19. Stránky projektu wxPython
    https://wxpython.org/
  20. wxPython Project Phoenix (na GitHubu)
    https://github.com/wxWidget­s/Phoenix/blob/wxPython-4.0.3/README.rst
  21. wxPython API Documentation
    https://docs.wxpython.org/index.html
  22. wxWidgets
    https://wxwidgets.org/
  23. wxPython 4.0.3 na PyPi
    https://pypi.org/project/wxPyt­hon/4.0.3/
  24. wxGlade – a GUI builder for wxWidgets
    http://wxglade.sourceforge.net/
  25. Repositář projektu wxGlade
    https://github.com/wxGlade/wxGlade/
  26. wxGlade’s documentation
    http://wxglade.sourceforge­.net/docs/index.html
  27. Graphical User Interfaces (GUI)
    https://pythonspot.com/gui/
  28. wxPyWiki
    https://wiki.wxpython.org/FrontPage
  29. Getting started with wxPython
    https://wiki.wxpython.org/Get­ting%20Started#A_First_Ap­plication:_.22Hello.2C_Wor­ld.22
  30. wxPython GUI tutorial
    https://pythonspot.com/wxpython-gui-tutorial/
  31. wxPython tutorial
    http://zetcode.com/wxpython/
  32. Build wxPython On Raspberry Pi
    https://wiki.wxpython.org/Bu­ildWxPythonOnRaspberryPi
  33. wxPython History
    https://wxpython.org/pages/his­tory/index.html
  34. Installing wxPython 4.0 (Project Phoenix) on Fedora 27
    https://blog.wizardsofthe­web.pro/installing-wxpython-on-fedora/
  35. Category:Software that uses wxWidgets
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_wxWidgets
  36. Hra Breakout napísaná v Tkinteri
    https://www.root.cz/clanky/hra-breakout-napisana-v-tkinteri/
  37. GUI Programming in Python
    https://wiki.python.org/mo­in/GuiProgramming
  38. Cameron Laird's personal notes on Python GUIs
    http://phaseit.net/claird/com­p.lang.python/python_GUI.html
  39. Python GUI development
    http://pythoncentral.io/introduction-python-gui-development/
  40. Hand Coded GUI Versus Qt Designer GUI
    https://stackoverflow.com/qu­estions/387092/hand-coded-gui-versus-qt-designer-gui
  41. Qt Creator Manual
    http://doc.qt.io/qtcreator/
  42. Qt Designer Manual
    http://doc.qt.io/qt-5/qtdesigner-manual.html
  43. Qt Creator (Wikipedia)
    https://en.wikipedia.org/wi­ki/Qt_Creator
  44. QIODevice
    https://pyside.github.io/doc­s/pyside/PySide/QtCore/QI­ODevice.html#PySide.QtCore­.QIODevice
  45. QFile
    https://pyside.github.io/doc­s/pyside/PySide/QtCore/QFi­le.html#PySide.QtCore.QFi­le
  46. QUiLoader
    https://pyside.github.io/doc­s/pyside/PySide/QtUiTools/QU­iLoader.html#PySide.QtUiTo­ols.PySide.QtUiTools.QUiLo­ader.load
  47. QSvgWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtSvg/QSvgWid­get.html
  48. QByteArray
    https://pyside.github.io/doc­s/pyside/PySide/QtCore/QBy­teArray.html
  49. Differences Between PySide and PyQt
    https://wiki.qt.io/Differen­ces_Between_PySide_and_PyQt
  50. PySide 1.2.1 tutorials
    https://pyside.github.io/doc­s/pyside/tutorials/index.html
  51. PySide tutorial
    http://zetcode.com/gui/py­sidetutorial/
  52. Drawing in PySide
    http://zetcode.com/gui/py­sidetutorial/drawing/
  53. Qt Core
    https://pyside.github.io/doc­s/pyside/PySide/QtCore/Qt­.html
  54. Signals & Slots
    http://doc.qt.io/qt-4.8/signalsandslots.html
  55. Signals and Slots in PySide
    http://wiki.qt.io/Signals_an­d_Slots_in_PySide
  56. Intro to PySide/PyQt: Basic Widgets and Hello, World!
    http://www.pythoncentral.io/intro-to-pysidepyqt-basic-widgets-and-hello-world/
  57. Leo editor
    http://leoeditor.com/
  58. IPython Qt Console aneb vylepšený pseudoterminál
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-ipython-a-ipython-notebook/#k06
  59. Python GUI development
    http://pythoncentral.io/introduction-python-gui-development/
  60. Graphic User Interface FAQ
    https://docs.python.org/2/faq/gu­i.html#graphic-user-interface-faq
  61. Tkinter
    https://wiki.python.org/moin/Tkinter
  62. Tkinter 8.5 reference: a GUI for Python
    http://infohost.nmt.edu/tcc/hel­p/pubs/Tkinter/web/index.html
  63. Tkinter (Wikipedia)
    https://en.wikipedia.org/wiki/Tkinter
  64. appJar
    http://appjar.info/
  65. appJar (Wikipedia)
    https://en.wikipedia.org/wiki/AppJar
  66. appJar na Pythonhosted
    http://pythonhosted.org/appJar/
  67. appJar widgets
    http://appjar.info/pythonWidgets/
  68. Stránky projektu PyGTK
    http://www.pygtk.org/
  69. PyGTK (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  70. Stránky projektu PyGObject
    https://wiki.gnome.org/Pro­jects/PyGObject
  71. Stránky projektu PyQt
    https://riverbankcomputin­g.com/software/pyqt/intro
  72. What's on the Kivy Roadmap?
    https://github.com/orgs/ki­vy/discussions/10
  73. Graphical user interface (Wikipedia)
    http://en.wikipedia.org/wi­ki/Graphical_user_interfa­ce
  74. The Real History of the GUI
    http://articles.sitepoint­.com/article/real-history-gui
  75. History of the graphical user interface (Wikipedia)
    http://en.wikipedia.org/wi­ki/History_of_the_graphical_u­ser_interface
  76. Creating a GUI with Python: A Comprehensive Guide
    https://coderivers.org/blog/how-to-create-a-gui-with-python/
  77. NiceGUI
    https://nicegui.io/
  78. Buildozer’s documentation
    https://buildozer.readthe­docs.io/en/latest/
  79. buildozer 1.5.0 na PyPi
    https://pypi.org/project/buildozer/
  80. Kivy 2.3.1 na PyPi
    https://pypi.org/project/Kivy/
  81. pyglet 2.1.11 na PyPi
    https://pypi.org/project/pyglet/
  82. pyglet Documentation
    https://pyglet.readthedoc­s.io/en/latest/
  83. Kivy: BoxLayout
    https://kivy-fork.readthedocs.io/en/latest/api-kivy.uix.boxlayout.html
  84. Box Layout
    https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html#module-kivy.uix.boxlayout
  85. Grid Layout
    https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html#module-kivy.uix.gridlayout
  86. Stack Layout
    https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html#module-kivy.uix.stacklayout
  87. Delphi (software)
    https://en.wikipedia.org/wi­ki/Delphi_(software)
  88. Visual Basic (classic)
    https://en.wikipedia.org/wi­ki/Visual_Basic_(classic)

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.