Obsah
1. Úvodní informace o knihovně Tk
2. Widgety a kontejnery
3. Základní typy widgetů v knihovně Tk
4. Vlastnosti widgetů
5. Události
6. Demonstrační příklady se základními widgety
7. Demonstrační příklady na práci s manažery umístění (geometrie)
8. Obsah dalšího pokračování tohoto seriálu
1. Úvodní informace o knihovně Tk
Tk je toolkit (z pohledu programovacího jazyka se přitom jedná o knihovnu či – jinými slovy řečeno – modul) určený pro jednoduchý a rychlý vývoj programů obsahujících grafické uživatelské rozhraní (Graphical User Interface – GUI). Autorem tohoto toolkitu je, podobně jako v případě programovacího jazyka Tcl, John Ousterhout, mezi jehož zájmy v minulosti patřila automatizace (skriptovatelnost) aplikací a právě tvorba grafických uživatelských rozhraní. V minulosti byl tento toolkit velmi oblíbený, proto se dodával (a stále dodává) spolu s instalací programovacího jazyka Tcl. I z tohoto důvodu se také v různých materiálech a dokumentech často setkáme se společným názvem Tcl/Tk. Samotný název Tk jednoduše znamená zkratku slovaToolKit. Udává se, že poměr psaného kódu v Tcl/Tk je vůči Motifu na hodnotách 1:20 a vůči základnímu Xlibu dokonce 1:100! (vše se samozřejmě týká tvorby grafického uživatelského rozhraní).
V průběhu postupného vývoje novějších (avšak ne nutně dokonalejších) programovacích nástrojů byla knihovna Tk použita v mnoha dalších programovacích jazycích. Pravděpodobně nejznámější je, samozřejmě kromě samotné dvojice Tcl/Tk, modul pro programovací jazyk Perl (Perl/Tk) a Python (Tkinter – Tk Interface), knihovnu Tk je však samozřejmě možné použít i v dalších programovacích jazycích, i když v mnoha případech ne tak snadně a efektivně jako ze samotného Tcl. V praxi se často s výhodou používá spojení programů napsaných v programovacím jazyku C či s C++ s grafickým uživatelským rozhraním, které je vytvořeno pomocí Tcl a Tk.
2. Widgety a kontejnery
Základem prakticky všech v současnosti používaných grafických uživatelských rozhraní jsou takzvané widgety, které jsou někdy poněkud nepřesně označovány také jako komponenty. Z pohledu uživatele aplikací s grafickým uživatelským rozhraním se jedná o grafické prvky zobrazené na obrazovce, které mají předem známé chování a předvídatelnou funkci. V mnoha případech je chování widgetů standardizováno či alespoň doporučováno – viz například doporučení pro Motif, Microsoft Windows a nověji také doporučení pro poměrně nové Gnome a KDE. Velká část widgetů se snaží svým vzhledem reflektovat objekty z reálného světa (tlačítka, „teploměry“, přepínače programů, objekty známé z papírových formulářů apod.). Z pohledu programátora je naproti tomu widget objektem, jemuž lze nastavit určitý stav a jenž reaguje na události, které při své práci generuje uživatel (přesouvání objektů na obrazovce, stlačování obrazů tlačítek pomocí myši či stylusu, psaní textu atd.).
Samotné widgety nejsou na obrazovce prakticky nikdy zcela osamocené – ve skutečnosti se téměř vždy nacházejí 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 (Root :-)) je představován plochou na obrazovce, na které jsou umístěna okna aplikací. V těchto oknech se dále nacházejí kontejnery a widgety. V mnoha grafických uživatelských rozhraních přitom mohou být vybrané widgety (zdaleka však ne všechny) současně i kontejnery. Kontejnery kromě jiného řeší i rozmístění widgetů na své ploše. Způsobů pro rozmisťování existuje více, základní dělení je na kontejnery, kde jsou widgety umisťovány absolutně (do této kategorie patří WinAPI, MFC, OWL a VCL), a naopak kontejnery, které widgety většinou umisťují podle své velikosti (zde se nachází AWT, Swing, GTK, Qt, Tk a mnoho dalších).
V toolkitu Tk se mohou widgety umisťovat několika různými způsoby (pack, place a grid), které si podrobněji popíšeme v šestém pokračování tohoto seriálu.
3. Základní typy widgetů v knihovně Tk
V průběhu mnoha let se množina widgetů používaných v různých grafických uživatelských rozhraních postupně rozšiřovala, ostatně postačí se podívat na obrázky z prvních grafických rozhraní navržených ve společnosti Xerox a porovnat je s moderním desktopem. Současně však také docházelo ke sjednocování vzhledu jednotlivých widgetů i chování na různých platformách (vzhled samozřejmě není na všech platformách přesně stejný, to však pro uživatele nepředstavuje významnější problém, na rozdíl od odlišného chování celého prostředí i jednotlivých widgetů, na rozdíl od chování widgetů).
V toolkitu Tk je k dispozici poměrně velké množství widgetů, podobně jako v dalších moderních toolkitech. V následující tabulce je uveden seznam základních typů widgetů. Pro mnoho aplikací je níže uvedená skupina widgetů dostačující, avšak v případě, že aplikace potřebuje vytvořit nový widget, je to samozřejmě možné, protože knihovna Tk je navržena tak, že ji lze poměrně jednoduchým způsobem rozšiřovat. V následující tabulce si také můžete všimnout toho, že některé widgety jsou pojmenovány odlišným způsobem od dnes používané terminologie – vychází to z faktu, že Tcl/Tk je mnohem starší než většina dnešních toolkitů.
Jméno widgetu | Význam a funkce |
---|---|
label | widget, který zobrazuje v okně či dialogu měnitelný text |
button | graficky zobrazené tlačítko, které implicitně reaguje na levé tlačítko myši |
checkbutton | dvoustavový přepínač, který implicitně reaguje na levé tlačítko myši |
radiobutton | widget, jichž může být sdruženo větší množství, vždy pouze jeden je vybraný |
scale | dnes nazýván pojmem slider atd., jedná se o widget s posuvnou částí a přidruženým textem, kde se zobrazuje hodnota v závislosti na poloze posuvné části |
entry | widget, do kterého je možné zapisovat text, k tomu má přidruženo mnoho klávesových zkratek (jde o kombinaci staršího a novějšího standardu) |
spinbox | widget určený pro zadávání číselných hodnot kombinací klávesnice a myši (i s kontrolou mezí) |
menu | vertikální menu, které se skládá z více položek |
menubutton | používá se spolu s menu pro vytváření jednotlivých položek |
listbox | widget, jež nabízí na výběr libovolné množství řádků s textem |
scrollbar | podobné widgetu scale s tím rozdílem, že zobrazuje posuvné šipky a naopak nezobrazuje přidruženou číselnou hodnotu |
frame | jeden z několika nabízených kontejnerů; tento má tvar obdélníka (může být také neviditelný nebo může mít 3D rámeček) |
toplevel | další z kontejnerů, tento se chová jako samostatné okno či dialog |
bitmap | bitmapa, tj. rastrový obrázek |
photo | rastrový obrázek, jež může být načten z externího souboru v mnoha různých formátech |
canvas | widget, na který lze programově vkládat další grafické komponenty (úsečky, oblouky, kružnice, polyčáry, text atd.) |
Výše zmíněné widgety budou popsány v dalších částech tohoto seriálu. Zde se pouze chci zmínit o pěkně pojatých menu. Jednotlivá vertikální menu se totiž mohou od mateřského okna „odpoutat“ a chovat se jako samostatné okno či dialog. Díky tomu lze celou aplikaci zachovat po grafické stránce velmi kompaktní a nechat na uživateli, zda a kdy si jednotlivá menu zobrazí v samostatných oknech. Aplikace přitom může používat jak hlavní menu, tak i libovolné množství menu příručních (kontextových, pop-up). Podobný způsob práce s menu je k vidění například u textového editoru Vim (ovšem pouze v některých prostředích).
4. Vlastnosti widgetů
Ke každému widgetu je možné nastavit mnoho různých vlastností, které mění buď jeho vizuální vzhled na obrazovce počítače, nebo jeho chování, tj. způsob reakce widgetu na akce uživatele. Mezi tyto akce počítáme například kliknutí tlačítkem myši, použití klávesnice (hot keys), přesunutí widgetu atd. Některé vlastnosti jsou všem widgetům společné, další vlastnosti jsou však jedinečné pro jeden či pouze několik typů widgetů – je to ostatně logické, některé widgety mají speciální chování. Vlastnosti lze nastavovat již při vytváření widgetů, na druhou stranu je také možné vlastnosti měnit až při běhu aplikace. Způsob nastavení vlastností si ukážeme na demonstračních příkladech. V následující tabulce jsou uvedeny vlastnosti, které jsou společné prakticky všem widgetům (kromě speciálních widgetů typu „položka menu“, které mají vlastnosti omezeny, stejně tak jako své reakce na uživatelovu činnost). Při programovém nastavení vlastnosti widgetu se před název vlastnosti přidává znak mínus: „-“.
Jméno vlastnosti | Popis vlastnosti |
---|---|
background | barva pozadí widgetu v případě, že widget není aktivní (vybraný) |
foreground | barva popředí widgetu (například zobrazeného textu) v případě, že widget není aktivní (vybraný) |
borderwidth | šířka okraje widgetu, která je zadaná v pixelech |
activebackground | barva pozadí widgetu v případě, že je widget vybrán (typicky kurzorem myši) |
activeforeground | barva popředí widgetu v případě, že je widget vybrán |
disabledforeground | barva popředí widgetu v případě, že je ovládání widgetu zakázáno |
relief | způsob prostorového zobrazení widgetu |
compound | způsob umístění bitmapy či obrázku na widgetu |
bitmap | bitmapa, která má být ve widgetu zobrazena |
image | obrázek, který má být ve widgetu zobrazen (více o bitmapách a obrázcích bude uvedeno v dalších dílech) |
font | jméno fontu, který je použit pro text uvnitř widgetu (font lze specifikovat platformově nezávislým způsobem) |
text | text, který má být ve widgetu (tlačítko, položka menu atd.) zobrazen |
cursor | jméno kurzoru myši, který bude použit v případě, že se kurzor nachází nad widgetem |
textvariable | jméno proměnné, která je nastavována podle uživatelových manipulací s widgetem |
justify | zarovnání textu ve widgetu v případě, že se zobrazuje více řádků |
anchor | způsob umístění textu či obrázku ve widgetu |
5. Události
Při programování grafických uživatelských rozhraní je často používán pojem události (event) – událostmi řízené programování je ostatně s programováním GUI prakticky neoddělitelně spojeno. Každý widget může v průběhu svého života generovat nějaké události. Naprostá většina událostí vzniká tak, že uživatel s widgetem interaktivně pracuje (například stiskne tlačítko zobrazené na obrazovce). Ke každému widgetu je příslušná jedna „implicitní“ událost, na kterou reaguje. Tato událost se nastavuje pomocí změny vlastnosti widgetu, což bude ukázáno v demonstračních příkladech v následujících dvou kapitolách. Kromě „implicitní“ události lze na widgety navázat i další události, například tlačítko (button) může reagovat i na stisknutí klávesy na klávesnici, na pravé tlačítko myši či na rolování kolečkem myši. Toto navázání se provádí pomocí příkazu bind, který obsahuje množství voleb. Musíme si však uvědomit, že některé události se na různých operačních systémech mohou generovat různým způsobem – typicky se jedná o přesun fokusu. I událostmi se budeme podrobněji zabývat v dalších částech tohoto seriálu.
6. Demonstrační příklady se základními widgety
V této kapitole budou ukázány jednoduché demonstrační příklady. Jejich spouštění je možné provádět z vizuálního shellu wish. Při spuštění tohoto shellu je již zobrazeno okno, do kterého je možné vkládat jak kontejnery, tak i jednotlivé widgety. Toto okno se tedy nemusí vytvářet programově.
Prakticky nejjednodušším příkladem je zobrazení okna s textovou informací. Tuto úlohu lze řešit tak, že se do okna vloží widget typu label, který požadovanou textovou informaci zobrazuje:
#!/usr/bin/wish
label .hello -text "Hello world!"
pack .hello
Na prvním obrázku je zobrazeno okno prvního demonstračního příkladu.
Obrázek 1: screenshot prvního demonstračního příkladu
Výše uvedený příklad není úplný, protože není naprogramováno uzavření okna. Tento problém vyřešíme tak, že do okna vložíme další widget, tentokrát typu button. Po stisknutí tohoto tlačítka se okno korektně uzavře:
#!/usr/bin/wish
label .hello -text "Hello world!"
button .close -text "Close window" -command {exit}
pack .hello
pack .close
Okno tohoto demonstračního příkladu je ukázáno na druhém obrázku.
Obrázek 2: screenshot druhého demonstračního příkladu
V příkladu lze samozřejmě měnit vlastnosti jednotlivých widgetů, například následovně:
#!/usr/bin/wish
label .hello -text "Hello world!"
button .close -text "Close window" -command {exit} -background red -activebackground green
pack .hello
pack .close
7. Demonstrační příklady na práci s manažery umístění (geometrie)
Nejjednodušším manažerem používaným pro umisťování widgetů je manažer grid. S použitím tohoto manažeru se widgety umisťují do neviditelné mřížky. Velikost mřížky je automaticky měněna tak, aby se do ní všechny vkládané widgety umístily v „rozumné“ velikosti. Programově je však možné měnit vzdálenost mezi jednotlivými widgety, a tím také měnit velikost mřížky. V dalším příkladu jsou do okna umístěny čtyři tlačítka (widgety typu button) do jedné mřížky:
#!/usr/bin/wish
button .prvni -text "First button" -command {exit}
button .druhy -text "Second button" -command {exit}
button .treti -text "Third button" -command {exit}
button .ctvrty -text "Fourth button" -command {exit}
grid .prvni -column 1 -row 1
grid .druhy -column 2 -row 1
grid .treti -column 1 -row 2
grid .ctvrty -column 2 -row 2
Umístění tlačítek je patrné ze třetího obrázku. Všimněte si, že bez dalšího explicitního nastavení je každé tlačítko pouze tak velké, aby se do něj vešel zadaný text.
Obrázek 3: screenshot třetího demonstračního příkladu
Můžeme si také vyzkoušet změnit umístění jednotlivých tlačítek v mřížce:
#!/usr/bin/wish
button .prvni -text "First button" -command {exit}
button .druhy -text "Second button" -command {exit}
button .treti -text "Third button" -command {exit}
button .ctvrty -text "Fourth button" -command {exit}
grid .prvni -column 2 -row 4
grid .druhy -column 3 -row 1
grid .treti -column 1 -row 3
grid .ctvrty -column 4 -row 2
Výsledek takto modifikovaného příkladu je patrný ze čtvrtého obrázku.
Obrázek 4: screenshot čtvrtého demonstračního příkladu
8. Obsah dalšího pokračování tohoto seriálu
V dalším pokračování tohoto seriálu budou podrobněji popsány nejpoužívanější widgety, které jsou knihovnou Tk uživatelům i programátorům nabízeny. Také si ukážeme různé způsoby umisťování widgetů pomocí manažerů geometrie.