Programovací jazyk TCL (13)

11. 10. 2005
Doba čtení: 12 minut

Sdílet

V dnešní části seriálu pojednávajícího o programovacím jazyku Tcl a toolkitu Tk bude probírána tvorba modálních i nemodálních dialogových oken včetně využívání předpřipravených (standardních) dialogových oken. Rovněž dokončíme část věnovanou nabídkám (menu) popisem zbývajícího - třetího - typu menu, který je toolkitem Tk programátorům nabízen.

Úvodník

V dnešní části seriálu pojednávajícího o programovacím jazyku Tcl a toolkitu Tk bude probírána tvorba modálních i nemodálních dialogových oken včetně využívání předpřipravených (standardních) dialogových oken. Rovněž dokončíme část věnovanou nabídkám (menu) popisem zbývajícího – třetího – typu menu, který je toolkitem Tk programátorům nabízen.

Obsah

1. Třetí typ menu dostupný z toolkitu Tk – tlačítkové menu
2. Praktický příklad využívající tlačítkové menu
3. Rozšířený příklad využívající tlačítkové menu
4. Zaškrtávací tlačítka v menu
5. Výběrová tlačítka v menu
6. Základy práce s dialogovými okny
7. Obecné dialogové okno tk_dialog
8. Obsah dalšího pokračování tohoto seriálu

1. Třetí typ menu dostupný z toolkitu Tk – tlačítkové menu

předchozí části tohoto seriálu jsme si popsali dva základní typy menu – roletové menu (pull down) a vynořující se menu (pop up). K této dvojici typů se v toolkitu Tk přidává i třetí typ – takzvané tlačítkové menu (button menu). Tento typ menu je vázán na nějaké tlačítko zobrazené v okně či dialogovém boxu. Mezi přednosti tlačítkového menu patří úspora místa (není stále viditelné jako roletové menu) a současně i vizuální informace pro uživatele, který o existenci menu bude vědět díky přítomnosti tlačítka (na rozdíl od vynořujícího se menu, jehož existence se uživateli nijak neukazuje). Na druhou stranu se může stát, že méně zkušení uživatelé budou zmateni z toho, že se po stisku tlačítka neprovede žádný příkaz, ale zobrazí se menu. Těchto uživatelů však bude ubývat, protože tlačítkové menu je použito i v desktopových prostředích GNOME, KDE a Microsoft Windows. V následujícím demonstračním příkladu je ukázáno, jakým způsobem se tlačítkové menu vytvoří pomocí příkazu menubutton (samotné tlačítko je pro odlišení vykresleno ve stylu „raised“). Také si všimněte, že pro zjednodušení přístupu k menu je možné použít zástupnou proměnnou, v našem případě pojmenovanou jednoduše m:

#!/usr/bin/wish

# Práce s menu pomocí toolkitu Tk
# První demonstrační příklad
wm title . "Práce s menu pomocí toolkitu Tk - I"
wm iconname . "Práce s menu I"

# přidání tlačítka [Edit] s přidruženým menu
menubutton .edit -menu .edit.menu -text "Edit" -relief raised -underline 0
set m .edit.menu
menu $m -tearoff 0

# vložení příkazů do menu [Edit]
$m add command -label "Cut" -underline 2
$m add command -label "Copy" -underline 0
$m add command -label "Paste" -underline 0
$m add command -label "Delete" -underline 2

# všechny widgety umístíme do okna aplikace
pack .edit -fill both

# finito 
TCL 13 - 1

Obrázek 1: Screenshot prvního demonstračního příkladu s menu na X Window systému

TCL 13 - 2

Obrázek 2: Screenshot prvního demonstračního příkladu s menu na Windows XP

2. Praktický příklad využívající tlačítkové menu

Druhý demonstrační příklad, podobně jako příklad první, taktéž využívá tlačítkové menu. Nejprve se do okna aplikace vykreslí pomocí widgetu canvas (plátno) kruh. Spolu s plátnem jsou v okně vytvořena tři tlačítka. Dvě z tlačítek ([Edit] a [Colors]) po svém stisknutí zobrazí tlačítkové menu, třetí tlačítko ([Exit]) běh aplikace bez dalších dotazů ukončí. Po zobrazení tlačítkového menu s výběrem barev je možné pomocí klávesnice nebo myši vybrat barvu výplně kruhu. Samotné menu, ve kterém je každá položka jinak podbarvena a obsahuje i klávesovou zkratku, je vytvořeno pomocí pouhých čtyř programových řádků s využitím „seznamové“ smyčky foreach (klávesovou zkratku je zde možné programově vytvořit proto, že žádná z uvedených barev nezačíná stejným písmenem). Vzhledem k tomu, že je tlačítkové menu vytvořeno s volbou -tearoff 1, je možné menu po jeho zobrazení „odtrhnout“, a vytvořit tak samostatné okno se seznamem příkazů. Poznámka: pomocí příkazů wm title a wm iconname se specifikují volby pro správce oken (WM – Window Manager), v tomto případě se jedná o titulek okna a popis ikony použitý v případě minimalizace aplikace nebo při zobrazení titulku aplikace v taskbaru.

#!/usr/bin/wish

# Práce s menu pomocí toolkitu Tk
# Druhý demonstrační příklad
wm title . "Práce s menu pomocí toolkitu Tk - II"
wm iconname . "Práce s menu II"

# vytvoření kreslicího plátna
canvas .canvas -width 320 -height 240

# přidání tlačítka [Edit] s přidruženým menu
menubutton .edit -menu .edit.menu -text "Edit" -relief raised -underline 0
set m .edit.menu
menu $m -tearoff 0

# vložení příkazů do menu [Edit]
$m add command -label "Cut" -underline 2
$m add command -label "Copy" -underline 0
$m add command -label "Paste" -underline 0
$m add command -label "Delete" -underline 2

# přidání dalšího tlačítka [Colors] s přidruženým menu
menubutton .colors -menu .colors.menu -text "Color" -relief ridge -underline 0
set m .colors.menu
menu $m -tearoff 1

# vložení příkazů pro změnu barvy do menu [Colors]
set colors {white yellow orange red magenta blue cyan green}
foreach c $colors {
    $m add command -label $c -background $c -underline 0 -command "setColor $c"
}

# procedura pro nastavení barvy výplně kruhu
proc setColor { color } {
    .canvas itemconfigure kruh -fill $color
}

# vytvoření kruhu
.canvas create oval [expr 160-80] [expr 120-80] [expr 160+80] [expr 120+80] -width 5 -tags kruh

# všechny widgety umístíme do okna aplikace
pack .edit -fill both
pack [button .exit -text "Exit" -command exit] -fill both
pack .canvas
pack .colors -fill both

# finito 
TCL 13 - 3

Obrázek 3: Screenshot druhého demonstračního příkladu s menu na X Window systému

TCL 13 - 4

Obrázek 4: Screenshot druhého demonstračního příkladu s menu na Windows XP

3. Rozšířený příklad využívající tlačítkové menu

V níže uvedeném třetím demonstračním příkladu je ukázána programová tvorba položek menu jak pomocí „seznamové“ smyčky typu foreach (viz předchozí demonstrační příklad), tak i klasické počítané smyčky typu for. Tlačítkové menu skryté pod tlačítkem [Colors] je vytvořeno pomocí seznamu a smyčky, která tímto seznamem iteruje, zatímco menu skryté pod tlačítkem [Widths] je vytvořeno počítanou smyčkou. Všimněte si také chyby (resp. nedostatku) při specifikaci horkých kláves u položek pro změnu šířky okraje kruhu – jak jednopixelová šířka (první položka menu), tak i desetipixelová šířka (desátá položka menu) mají přiřazenu shodnou horkou klávesu. Chování menu v takovém případě závisí na použitém grafickém uživatelském rozhraní. V některých GUI systémech se při stisknutí konfliktní horké klávesy ihned vyvolá první příkaz, v jiných systémech se přeskakuje mezi všemi možnými variantami a uživatel musí pro potvrzení použít klávesu [Enter] nebo [Space].

#!/usr/bin/wish

# Práce s menu pomocí toolkitu Tk
# Třetí demonstrační příklad
wm title . "Práce s menu pomocí toolkitu Tk - III"
wm iconname . "Práce s menu III"

# vytvoření kreslicího plátna
canvas .canvas -width 320 -height 240

# přidání tlačítka [Edit] s přidruženým menu
menubutton .edit -menu .edit.menu -text "Edit" -relief raised -underline 0
set m .edit.menu
menu $m -tearoff 0

# vložení příkazů do menu [Edit]
$m add command -label "Cut" -underline 2
$m add command -label "Copy" -underline 0
$m add command -label "Paste" -underline 0
$m add command -label "Delete" -underline 2

# přidání dalšího tlačítka [Colors] s přidruženým menu
menubutton .colors -menu .colors.menu -text "Color" -relief ridge -underline 0
set m .colors.menu
menu $m -tearoff 1

# vložení příkazů pro změnu barvy do menu [Color]
set colors {white yellow orange red magenta blue cyan green}
foreach c $colors {
    $m add command -label $c -background $c -underline 0 -command "setColor $c"
}

# přidání dalšího tlačítka [Widths] s přidruženým menu
menubutton .widths -menu .widths.menu -text "Width" -relief ridge -underline 0
set m .widths.menu
menu $m -tearoff 1

# vložení příkazů pro změnu šířky okraje kruhu do menu [Widths]
for {set w 1} {$w<=10} {incr w} {
    $m add command -label $w -underline 0 -command "setWidth $w"
}

# procedura pro nastavení barvy výplně kruhu
proc setColor { color } {
    .canvas itemconfigure kruh -fill $color
}

# procedura pro nastavení šířky okraje kruhu
proc setWidth { width } {
    .canvas itemconfigure kruh -width $width
}

# vytvoření kruhu
.canvas create oval [expr 160-80] [expr 120-80] [expr 160+80] [expr 120+80] -width 5 -tags kruh

# všechny widgety umístíme do okna aplikace
pack .edit -fill both
pack [button .exit -text "Exit" -command exit] -fill both
pack .canvas
pack .colors -fill both
pack .widths -fill both

# finito 
TCL 13 - 5

Obrázek 5: Screenshot třetího demonstračního příkladu s menu na X Window systému

TCL 13 - 6

Obrázek 6: Screenshot třetího demonstračního příkladu s menu na Windows XP

4. Zaškrtávací tlačítka v menu

Ve všech typech menu je možné použít i zaškrtávací tlačítka. Tato tlačítka se od běžných příkazových tlačítek liší tím, že s sebou mohou nést jednu pravdivostní hodnotu: true/false. Tento typ položek menu tedy nahrazuje check boxy použité v dialogových oknech. Graficky je zaškrtávací tlačítko zobrazeno tak, že se kromě textu a případné ikony u položky menu objevuje prázdný či vyplněný symbol zaškrtnutí. Přesná podoba a umístění symbolu je závislá na použitém grafickém uživatelském rozhraní a nastaveném stylu (resp. skinu). Typicky je tento symbol umístěn vlevo od textu se zarovnáním k levému okraji menu. Zaškrtávací tlačítka se vytváří pomocí příkazu jméno_menu add check s případným uvedením globální proměnné, která bude sledovat stav tlačítka, například: jméno_menu add check -label „Word wrap“ -variable wordWrap.

5. Výběrová tlačítka v menu

Kromě zaškrtávacích tlačítek je možné v menu použít i výběrová tlačítka. Zatímco byla zaškrtávací tlačítka na sobě nezávislá, u výběrových tlačítek je zaručeno, že bude vybráno maximálně jedno z nich (nemusí však být vybráno žádné). Výběrová tlačítka v menu se tak do značné míry podobají radio buttonům používaným v dialogových boxech; například i tím, že mohou nastavovat hodnotu předem zadané globální proměnné. Výběrová tlačítka se vytvářejí pomocí příkazu jméno_menu add radio, jak je ostatně patrné ze čtvrtého demonstračního příkladu. Na níže uvedených screenshotech si všimněte zejména zcela rozdílného pojetí tvarů výběrových tlačítek. Zatímco se v X Window systému tvary tlačítek podobají radio buttonům z dialogových boxů, na Windows XP se ztratila veškerá dekorace tlačítek a zbyly „pouhé“ znaky pro zaškrtnutí (což je samo o sobě zajímavé, protože ve WinAPI je možné použít i bullet, který by zde byl vhodnější). Je však samozřejmé, že na obou zmíněných systémech lze docílit i jiného způsobu zobrazení, zejména na X Window systému záleží na volbě sady widgetů, které slouží jako podklad pro toolkit Tk.

#!/usr/bin/wish

# Práce s menu pomocí toolkitu Tk
# Čtvrtý demonstrační příklad
wm title . "Práce s menu pomocí toolkitu Tk - IV"
wm iconname . "Práce s menu IV"

# vytvoření kreslicího plátna
canvas .canvas -width 320 -height 240

# přidání tlačítka [Edit] s přidruženým menu
menubutton .edit -menu .edit.menu -text "Edit" -relief raised -underline 0
set m .edit.menu
menu $m -tearoff 0

# vložení příkazů do menu [Edit]
$m add command -label "Cut" -underline 2
$m add command -label "Copy" -underline 0
$m add command -label "Paste" -underline 0
$m add command -label "Delete" -underline 2

# přidání dalšího tlačítka [Colors] s přidruženým menu
menubutton .colors -menu .colors.menu -text "Color" -relief ridge -underline 0
set m .colors.menu
menu $m -tearoff 1

# vložení příkazů pro změnu barvy do menu [Colors]
set colors {white yellow orange red magenta blue cyan green}
foreach c $colors {
    $m add command -label $c -background $c -underline 0 -command "setColor $c"
}

# přidání dalšího tlačítka [Widths] s přidruženým menu
menubutton .widths -menu .widths.menu -text "Width" -relief ridge -underline 0
set m .widths.menu
menu $m -tearoff 1

# vložení příkazů pro změnu šířky okraje kruhu do menu [Widths]
for {set w 1} {$w<=10} {incr w} {
    $m add radio -label $w -underline 0 -command "setWidth $w"
}

# procedura pro nastavení barvy výplně kruhu
proc setColor { color } {
    .canvas itemconfigure kruh -fill $color
}

# procedura pro nastavení šířky okraje kruhu
proc setWidth { width } {
    .canvas itemconfigure kruh -width $width
}

# vytvoření kruhu
.canvas create oval [expr 160-80] [expr 120-80] [expr 160+80] [expr 120+80] -width 5 -tags kruh

# všechny widgety umístíme do okna aplikace
pack .edit -fill both
pack [button .exit -text "Exit" -command exit] -fill both
pack .canvas
pack .colors -fill both
pack .widths -fill both

# finito 
TCL 13 - 7

Obrázek 7: Screenshot čtvrtého demonstračního příkladu s menu na X Window systému

TCL 13 - 8

Obrázek 8: Screenshot čtvrtého demonstračního příkladu s menu na Windows XP

6. Základy práce s dialogovými okny

Dialogová okna jsou v grafických uživatelských prostředích využívána poměrně často. Tyto prvky grafického uživatelského rozhraní vlastně vznikly postupnou evolucí. První aplikace s GUI většinou obsahovaly jednoduché drop-down menu, které se dále nevětvilo. Se zvyšující se složitostí aplikací se menu začalo postupně větvit až do chvíle, kdy se překročil určitý bod komplexnosti a práce s menu se stávala neefektivní. V tomto bodě se začaly vytvářet (většinou modální) dialogová okna, která na své ploše sdružovala několik ovládacích prvků. Jak však z každodenní zkušenosti víme, i dialogová okna se brzy zaplnila a pro jejich zjednodušení (resp. rozčlenění) se v dnešní době používá několik řešení: okna se záložkami (notebook, tabbed notebook), ikony po straně okna sdružující vzájemně související operace (použito například ve Firefoxu), nebo postupné procházení několika dialogy ve stylu „wizardů“.

Kromě zvládnutí vyšší komplexnosti aplikací hrají dialogová okna i další roli – pomáhají standardizovat některé společné části aplikací. Například pro otevření souboru, uložení souboru, tisk dokumentu nebo výběr barvy je možné (a velmi vhodné) použít standardní dialog dodávaný s GUI systémem. Do jaké míry se tento systém standardizace využívá, čtenář patrně vidí na svém desktopu sám: určitá míra standardizace je patrná, také je však zřejmé, že mnohé aplikace využívají jiné GUI knihovny, o míchání několika desktopových prostředí ani nemluvě (to zdaleka není pouze problém GNU softwaru, „lidová tvořivost“ je vidět i na komerčních programech). Při práci s dialogovými okny rozlišujeme dialogy modální a nemodální. Modální dialogy převezmou řízení celé aplikace a nedovolí uživateli pokračovat v práci, dokud nevybere z dialogu nějaký příkaz. Naproti tomu jsou nemodální okna zobrazena „paralelně“ s aplikací a neblokují vstup do aplikace (kromě toho, že jsou většinou zobrazena nad aplikací). Vzhledem k tomu, že jsou modální okna programátorsky jednodušeji zvládnutelná, používají se častěji, a to i v případech, kdy modální okno uživatele zdržuje či mu komplikuje práci. Typickým příkladem je dialog pro vyhledávání (například řetězců), který by měl být prakticky vždy nemodální, ale mnohé aplikace ho implementují jako modální.

V každém případě však Tcl/Tk umožňuje použití několika standardních dialogů pro nejčastěji používané činnosti se soubory a dokumenty. Kromě toho je možné pomocí jednoho příkazu vytvořit i vlastní dialogové okno, složitější dialogová okna se vytvářejí podobně jako každé jiné okno (pouze se musí nastavit modalita, pokud je vyžadována).

7. Obecné dialogové okno tk_dialog

Pro vytváření obecných dialogových oken pomocí toolkitu Tk slouží příkaz tk_dialog. Pomocí tohoto příkazu je možné vytvořit dialog, který obsahuje prakticky libovolné množství tlačítek, typicky se používají kombinace tlačítek [Yes] [No] a [Ok] [Cancel] případně [Yes] [No] [Help] a [Ok] [Cancel] [Help], fantazii při pojmenovávání tlačítek se však meze nekladou. Kromě tlačítek je možné v dialogu zobrazit i bitovou mapu s vhodným obrázkem a změnit titulek okna, pomocí kterého je dialog zobrazen. Po zavolání funkce tk_dialog se dialogové okno zobrazí a čeká se na vstup od uživatele. Pokud si uživatel vybere nějaké tlačítko, je identifikátor tohoto tlačítka (ve formě číselného indexu) vrácen zpět aplikaci a dialogové okno se uzavře. Pokud je zapotřebí reagovat přímo na stisknutí nějakého tlačítka, je možné k tomuto účelu využít funkce grab a tkwait. Příklady použití příkazu tk_dialog budou uvedeny v další části tohoto seriálu.

bitcoin_skoleni

8. Obsah dalšího pokračování tohoto seriálu

V dalším pokračování tohoto seriálu si ukážeme praktické použití dialogového okna vytvářeného pomocí příkazu tk_dialog. Také si řekneme, jakým způsobem je možné použít standardní dialogová okna.

Autor článku

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