Stručný průvodce vytvářením GUI v Tk
Eduard Sojka
URO, Léto 2003/4
VŠB – Technická univerzita Ostrava
2
Tk: stručný průvodce
Tk je knihovna prvků GUI.
Byla integrována do jazyků Tcl a Python.
Lze ji ale také volat z programů v C/C++. (Této možnosti se však nevyužívá často. Nejčastější je použití prostřednictvím jazyka Tcl, což zde ukážeme).
Tcl je skriptovací jazykem. Lze jej považovat za vhodný pro vytváření GUI a sestavování aplikací z částí.
Tcl není jazykem vhodným k vytváření celých aplikací (např. včetně částí řešících matematické a technické výpočty – v těchto částech je na místě použít zejména C, C++).
Co je Tk, Tcl/Tk?
3
Tk: stručný průvodce
Tvorba GUI je zde zpravidla jednodušší než v C/Java.
Vystačí se jen s intuitivní znalostí některých pojmů (třídy, události, posluchači…).
Dá se vcelku rychle naučit.
Existuje na všech platformách (dokonce i v Javě – Jacl).
Použitelné nejen pro vytvářeni GUI, ale současně také pro sestavování („slepování“) aplikací.
Můžete vytvářet nové příkazy jazyka (Tcl/C).
Několik důvodů, proč může být užitečné o Tcl/Tk něco vědět
4
Tk: stručný průvodce
Jazyk Tcl byl konstruován tak, aby měl co nejjednodušší syntaxi. Ta se ale programátorům může zdát nezvyklá.
Jazyk je interpretovaný. K vaší aplikaci musí být interpret. Nebo musíte interpret do vaší aplikace „přibalit“.
„Look and Feel“ je pro každou platformu pevný, navíc platformě neodpovídá úplně přesně (hlavně Windows).
Ačkoli je stále používán a modernizován, lze budoucnost Tcl/Tk jen těžko odhadnout.
Několik důvodů, proč se vám Tcl/Tk líbit nemusí
5
Tk: stručný průvodce
Ad pojem „look and feel“ Win, Motif, Java (Metal)
6
Tk: stručný průvodce
Nejprve uvedeme stručný přehled syntaxe jazyka Tcl.
Ale jen tolik, abyste byli schopni sledovat tento text, tedy tvorbu GUI s využitím Tk.
Více na cvičení, chcete-li.
Nežádáme, abyste v Tcl/Tk uměli bravurně programovat.
Jen bychom chtěli, abyste si udělali si vlastní názor.
Než začneme …
7
Tk: stručný průvodce
Hlavní konstrukcí jazyka je příkaz. Ten má tvar:
cmd arg1 arg2 …
set x 1.234
Např:
set jmeno Oscar
set jmeno "Oscar Wilde"
Povšimněte si, že jenoslovné řetězce nemusí mít apostrofy. Apostrofy mají ovšem obecnější význam (cvičení).
set je přiřazovací příkaz
8
Tk: stručný průvodce
Vnořené příkazy, jsou odděleny hranatými závorkami.
[…]
set y [expr $x + 1.234]
Např: expr vyhodnocuje aritmetický výraz
$ provádí substituci hodnoty proměnné
Povšimněte si, že expr zřejmě vrací hodnotu – je tedy funkcí.
9
Tk: stručný průvodce
Složené závorky slouží k seskupování prvků.
{…}
proc myCmd { x y }{ frame … button … }
Např: Příkaz proc definuje nový příkaz. Musí mít tři argumenty. Jméno nového příkazu, seznam jeho parametrů a seznam příkazů, které má provádět. (Interpretace obsahu seznamů v závorkách bude provedena až při vyvolání příkazu myCmd.)
10
Tk: stručný průvodce
Konce řádků jsou důležité
Ostatní pravidla:
Oddělení příkazů na jednom řádku
Příkaz bude pokračovat na dalším řádku
;
\
11
Tk: stručný průvodce
Volání příkazů (funkcí) Tk respektuje syntaxi Tcl. Navíc jako argumenty často uvidíte dvojice nastavující nějaké vlastnosti prvků GUI. Vypadají takto:
cmd … -vlastnost hodnota …
12
Tk: stručný průvodce
label .la -text "Toto je popiska."pack .la
Tečka znamená hlavní okno. Příkaz label zde vytvoří popisku nazvanou la, a to v hlavním okně (.). Příkaz pack provede formátování a vykreslení.
label1.tcl
13
Tk: stručný průvodce
label .la -text "abc" pack .la….la configure -text "Změna textu\npopisky."
Obsah popisky se dá dodatečně měnit. Také si povšimněte, že „.la“ se chová jako příkaz (byl nainstalován příkazem label) a vzpomeňte si na to i později.
label2.tcl
14
Tk: stručný průvodce
button .b -text "Konec" -command exitpack .b
Tlačítko (umístěné v hlavním okně), na které je navázán příkaz ukončení programu.
button1.tcl
15
Tk: stručný průvodce
frame .f -bd 2 -relief sunkenbutton .f.b -width 15 -height 2 -text "Konec"\ -command exitpack .fpack .f.b -padx 32 -pady 16
Tkačítko je nyní v rámci f. Ten je zahloubený (-relief sunken) a má okraj 2 (-bd 2). Tlačítko má předepsané rozměry (15, 12).
Odsazení tlačítka od sousedních objektů je 32 bodů ve směru x a 16 ve směru y.
button2.tcl
16
Tk: stručný průvodce
set myfont [font create -family {Helvetica} \ -size 12 -weight bold -slant italic]
button .b -text "Konec" -font $myfont\ -foreground #ff0000 -command exit
pack .b -padx 8 -pady 8
Zde má tlačítko vlastní font a barvu. Jinak je vše při starém. (myfont je proměnná, font je příkaz)
button3.tcl
17
Tk: stručný průvodce
button .b -image [image create photo -file "exit.gif"]\ -command exit
pack .b -padx 8 -pady 8
Zde je na tlačítku obrázek.
button4.tcl
18
Tk: stručný průvodce
entry .enbutton .bv -text "Vymazat" -width 10\ -command vymazbutton .bz -text "Zpracovat" -width 10\ -command zpracujlabel .la -foreground #ff0000
Ukázka vstupu a jeho zpracování. Prohlédněte si příkazy vymaz a zpracuj na následující straně.
entry1.tcl
19
Tk: stručný průvodce
pack .en -side top -padx 4 -pady 4 -fill xpack .la -side bottom -pady 4pack .bv -side left -pady 4pack .bz -side right -pady 4…proc vymaz {} { .en delete 0 end }proc zpracuj {} { .la configure -text [.en get] }
bind .en <Return> {zpracuj}focus .en
Pokračování: Příkaz .en delete 0 end maže text od pozice 0 až do konce, .en get získává text. Také si povšimněte příkazů bind, focus.
20
Tk: stručný průvodce
frame .fz -bd 2 -relief ridge entry .fz.en -width 16 button .fz.buvy -text "Vymaz" -command vymazbutton .buko -text "Konec" -command exit
pack …
Zde si, prosím, povšimněte práce formátovacího příkazu pack. Podrobnější komentář naleznete na dalším snímku.
entry2.tcl
21
Tk: stručný průvodce
pack .fz -side left -padx 2 -pady 2 pack .fz.en -padx 4 -pady 4 pack .fz.buvy -padx 4 -pady 4pack .buko -side right -fill y …
Jak pracuje pack? Prvky, které si nejsou nadřízeny/podřízeny (zde např. .fz.en, .fz.buvy), umísťuje shora a centrovaně pod sebe v pořadí, jak jste je uvedli, do místa, které v rodičovském prvku ještě zbývá. Toto pravidlo můžete změnit pomocí volby –side (left, right, bottom, top). Při umisťování je prvkem zabrán pruh plné šířky (volba top, bottom) nebo výšky (left, right) zbývající části rodičovského prvku. Často je zapotřebí vytvářet složitější hierar-chické struktury prvků jen kvůli formátovaní. Volby -fill x, -fill y, -fill both způsobí, že je prvek ve specifikovaném směru roztažen do celého zbývajícího místa rodičovského prvku. Kromě příkazu pack lze také použít příkazu grid.
22
Tk: stručný průvodce
pack .fz -side left -padx 2 -pady 2 pack .fz.en -padx 4 -pady 4 pack .fz.buvy -padx 4 -pady 4pack .buko -padx 2 -pady 2 -side right -fill y
23
Tk: stručný průvodce
label .la -text "A pair of radio buttons"radiobutton .r1 -text "Times" -variable fo\ -value "times"radiobutton .r2 -text "Helvetica" -variable fo\ -value "helvetica"button .bu -text Ukaz -command ukaz
proc ukaz { } { global fo; .la configure -font "-family $fo"}
.r1 select
Knoflíky jsou svázány s proměn-nou fo, do níž zapisují hodnoty “times“ nebo “helvetika“.
Všimněte si: global fo a $fo. Doplňte si příkazy pack (viz radio1.tcl).
radio1.tcl
24
Tk: stručný průvodce
label .la -text "Two check buttons"checkbutton .c1 -text "Bold" -variable bocheckbutton .c2 -text "Italics" -variable itbutton .bu -text "Ukaz" -command ukaz
proc ukaz { } { global bo it if {$bo} {set weight "bold"}else {set weight "normal"} if {$it} {set slant "italic"} else {set slant "roman"} .la configure -font "-weight $weight -slant $slant"}
Knoflíky jsou zde svázány s proměnnými bo, it. (Příkazy pack jsou zde opět vynechány.)
check1.tcl
25
Tk: stručný průvodce
listbox .li -width 12 -height 3label .la -text "nic" -foreground red
pack .li; pack .la
.li insert 0 Tatra Areo Skoda
# Nekdy pozdeji listbox doplnime.li insert end Wikov Jawa.li configure -height 5
bind .li <Double-B1-ButtonRelease> {\.la configure -text [.li get active]}
První argument insert udává místo, kam se má vkládat.
listbox1.tcl
26
Tk: stručný průvodce
scrollbar .sc -command ".li yview"listbox .li -yscroll ".sc set" -height 5label .la -foreground red
.li insert 0 Tatra Areo Skoda Wikov Jawa Praga Z
proc setLabel { value } { .la configure -text $value }bind .li <Double-B1-ButtonRelease> {setLabel\ [.li get active]}
.li yview specifikuje, že při manipulaci s ní má rolovací lišta volat příkaz .li yview--- (systém sám doplní: moveto číslo, scroll číslo). Listbox se naopak na lištu obrací pomocí příkazu .sc set --- (systém doplňuje dvě čísla) . .li get active vrací vybraný prvek.
listbox2.tcl
27
Tk: stručný průvodce
grid .li -row 0 -column 0grid .sc -row 0 -column 1 -sticky nsgrid .la -row 1 -column 0 -columnspan 2
Povšimněte si práce formátovacího příkazu „grid“. Volba -sticky ns zde způsobí roztažení lišty na celou výšku buňky, -columnspan 2 umísťuje přes dva sloupce dohromady.
28
Tk: stručný průvodce
spinbox .sb -values {leden unor brezen duben}label .la -foreground redbutton .bu -text OK -command buokpack …
.sb set brezenproc buok {} {.la configure -text [.sb get]}
Spinbox je entry + pomoc (zde výběr ze seznamu). Seznam hodnot je neměnný.
spinbox1.tcl
29
Tk: stručný průvodce
spinbox .sb -from 2.0 -to 3.0 -increment 0.1label .la -foreground redbutton .bu -text OK -command buok
pack …
.sb set 2.5proc buok {} {.la configure -text [.sb get]}
Spinbox s čísly rostoucími o zadaný přírůstek.
spinbox2.tcl
30
Tk: stručný průvodce
canvas .ca -width 250 -height 150pack .ca
.ca create line 25 25 125 125 -width 2 -fill red
.ca create oval 125 25 225 125 -fill blue
Kromě úsečky a oválu mohou být ještě arc, bitmap, image, polygon, rectangle a text. Později (canvas4.tcl) ještě ukážeme, jak lze s objekty pohybovat.
canvas1.tcl
31
Tk: stručný průvodce
canvas .ca -width 384 -heigh 288pack .caimage create photo "image1" -file "auto1.gif".ca create image 2 2 -anchor nw -image "image1".ca create oval 250 150 350 250 -fill blue
Řetězec “image1“ je identifikátor obrazu (může být i v pro-měnné). Volba 2 2 –anchor nw znamená, že obraz je umístěn do bodu 2 2 svým levým horním rohem.
canvas2.tcl
32
Tk: stručný průvodce
scrollbar .sy -orient vertical -command ".ca yview"scrollbar .sx -orient horizontal -command ".ca xview"canvas .ca -width 200 -height 100\
-scrollregion "0 0 400 250"\-xscrollcommand ".sx set"\-yscrollcommand ".sy set"
grid .ca -row 0 -column 0 grid .sy -row 0 -column 1 -sticky nsgrid .sx -row 1 -column 0 -sticky we
.ca create …
Povšimněte si specifikace –scrollregion “xmin ymin xmax zmax“ . Jinak je vše stejné jako u příkladu s listboxem.
canvas3.tcl
33
Tk: stručný průvodce
text .t -width 24 -height 6button .b -text "Uložit a konec" -command ulozit
pack …
proc ulozit { } { set file [open "text1.txt" w] puts $file [.t get 0.0 end] close $file exit}
Šířka a výška textového pole se myslí v počtu znaků. Konstrukce .t get 0.0 end vrací text od znaku 0 v řádku 0 až po konec textu. Podrobněji o možnostech vzhledu textu a editování v manuálu.
text1.tcl
34
Tk: stručný průvodce
scale .sc -orient horizontal -length 200 -from 0\ -to 100 -tickinterval 20 -command scgetvallabel .la -foreground red
pack .scpack .la -pady 8
.sc set 50proc scgetval { val } {.la configure -text $val }
V tomto příkladě stupnice při každé změně hodnoty vyvolá příkaz scgetval a hodnotu mu předá jako parametr.
scale1.tcl
35
Tk: stručný průvodce
frame .m -relief raised -borderwidth 1
menubutton .m.file -text "File" -menu .m.file.menu
menu .m.file.menu .m.file.menu add command -label Open\ -command myopen .m.file.menu add separator .m.file.menu add command -label Quit -command exit
pack .m -fill x; pack .m.file -side left -padx 1m
.m je rámec pro horní lištu s knoflíky. Čárkovaný oddělovač lze odstranit volbou -tearoff 0 v příkazu menu (změní se ale číslování položek, protože oddělovač je položka 0).
menu1.tcl
36
Tk: stručný průvodce
# Ukazka pozdejsiho nastaveni dostupnosti polozky
.m.file.menu entryconfigure 1 -state normal
.m.file.menu entryconfigure 1 -state disabled
# Ukazka pozdejsiho doplneni menu o dalsi polozku
.m.file.menu insert 2 command -label Neco\ -underline 0 -command nic
Lze ovládat dostupnost položek a další položky přidávat nebo ubírat. Jen volba –underline 0 stačí k tomu, aby volba Něco fungovala tak, jak je obvyklé. K vypouštění slouží volba delete.
menu1.tcl
37
Tk: stručný průvodce
menu .m.file.menu .m.file.menu add cascade -label "Kaskáda ... "\ –menu .m.file.menu.casc menu .m.file.menu.casc.m.file.menu.casc add command -label "Volba 1" ….m.file.menu.casc add command -label "Volba 2" …
Místo add command se zde použije add cascade
menu2.tcl
38
Tk: stručný průvodce
menu .m.file.menu .m.file.menu add command -label Quit -underline 0\
-accelerator <Ctrl-c> -command exitpack …
# Aby to fungovalo, musi mit focus hlavni okno.
bind . <Control-c> {exit}bind . <Key-f> {tk_popup .m.file.menu 100 100}bind . <Key-F1> {tk_messageBox -title About \
-message "URO 2003-4" -type ok \-icon info -parent .}
Akcelerátory
menu3.tcl
39
Tk: stručný průvodce
frame .m -relief raised -borderwidth 1
menubutton .m.file -menu .m.file.menu –image\ [image create photo -file "file.gif"]
menu .m.file.menu
.m.file.menu add command -compound left –image\ [image create photo -file "copy.gif"] -label "Copy"
.m.file.menu add command -image [image create photo -file "exits.gif"] -command exit
Menu s obrázky. Obrázky lze kombinovat s textem.
menu4.tcl
40
Tk: stručný průvodce
proc myopen { } { set types {{"Source files" {.tcl .c .h}} {"All files" *}} set fileName [tk_getOpenFile -filetypes $types\ -parent .] set file [open $fileName r+] .t insert end [read $file] close $file}
V tomto příkladě se obsah otevřeného souboru připojí k textovému poli .t.
filedialog1.tcl
41
Tk: stručný průvodce
tk_messageBox -title About –message\ "URO 2003-4" -type ok -icon info -parent .
set odpoved [tk_messageBox -title Dotaz\ -message "Pokracovat?" -type yesno\ -icon question -parent .]
message1.tcl
42
Tk: stručný průvodce
button .bu -text "Vytvorit…" \-command noveOkno
proc noveOkno { } { .bu configure -state disabled toplevel .w1; wm title .w1 "Nove" label .w1.la -text "Toto je nove okno." button .w1.bu -text "Zrusit toto\n okno"\
-command zrusitOkno pack .w1.la …}
proc zrusitOkno { } { destroy .w1 .bu configure -state normal}
viceoken1.tcl
43
Tk: stručný průvodce
package require Iwidgets 4.0iwidgets::tabnotebook .tnb -width 3i -height 1.5i
# Page #1set page [.tnb add -label "Osobni"]
frame $page.frlabel $page.fr.laj -text "Jmeno:"entry $page.fr.enj -width 12label $page.fr.lap -text "Prijmeni:"entry $page.fr.enp -width 12
kartoteka1.tcl
44
Tk: stručný průvodce
Myšlenka propojení je tato: vytvoříte vlastní příkaz, který budete volat tak, jak je v Tcl obvyklé:
Propojení Tcl/Tk s programy/moduly v C
myCommand arg1 arg2 …
Pro platformu MSW příkaz vytvoříte jako funkci v C, kterou zařadíte do DLL knihovny. Způsob vytvoření a předání dat je patrný z příkladu v souboru myCommands.c. Vaši knihovnu pak zpřístupníte provedením příkazu
load myCommands.dll
45
Tk: stručný průvodce
Myšlenka propojení je tato: vytvoříte vlastní příkaz, který budete volat tak, jak je v Tcl obvyklé:
Propojení Tcl/Tk s programy/moduly v C
myCommand arg1 arg2 …
Pro platformu MSW příkaz vytvoříte jako funkci v C, kterou zařadíte do DLL knihovny. Způsob vytvoření a předání dat je patrný z příkladu v souboru myCommands.c. Vaši knihovnu pak zpřístupníte provedením příkazu
load myCommands.dll
46
Tk: stručný průvodce - Co dál? …
Podle potřeby používejte manuálu Tcl/Tk
www.tcl.tk www.scriptics.com www.activestate.com
Navštivte