Stručný průvodce vytvářením GUI v Tk Eduard Sojka URO, Léto 2003/4 VŠB – Technická univerzita Ostrava
Co je Tk, Tcl/Tk? 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++).
Několik důvodů, proč může být užitečné o Tcl/Tk něco vědět Tk: stručný průvodce Několik důvodů, proč může být užitečné o Tcl/Tk něco vědět 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č se vám Tcl/Tk líbit nemusí Tk: stručný průvodce Několik důvodů, proč se vám Tcl/Tk líbit nemusí 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.
Ad pojem „look and feel“ Tk: stručný průvodce Ad pojem „look and feel“ Win, Motif, Java (Metal)
Než začneme … 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.
cmd arg1 arg2 … Tk: stručný průvodce Hlavní konstrukcí jazyka je příkaz. Ten má tvar: cmd arg1 arg2 … Např: set x 1.234 set je přiřazovací příkaz 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í).
[…] Tk: stručný průvodce Vnořené příkazy, jsou odděleny hranatými závorkami. […] Např: expr vyhodnocuje aritmetický výraz set y [expr $x + 1.234] $ provádí substituci hodnoty proměnné Povšimněte si, že expr zřejmě vrací hodnotu – je tedy funkcí.
{…} Tk: stručný průvodce Složené závorky slouží k seskupování prvků. 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.) proc myCmd { x y }{ frame … button … }
Ostatní pravidla: ; \ Tk: stručný průvodce Konce řádků jsou důležité Oddělení příkazů na jednom řádku \ Příkaz bude pokračovat na dalším řádku
cmd … -vlastnost hodnota … 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 …
label .la -text "Toto je popiska." pack .la 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
.la configure -text "Změna textu\npopisky." 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
button .b -text "Konec" -command exit pack .b Tk: stručný průvodce button .b -text "Konec" -command exit pack .b Tlačítko (umístěné v hlavním okně), na které je navázán příkaz ukončení programu. button1.tcl
frame .f -bd 2 -relief sunken Tk: stručný průvodce 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). frame .f -bd 2 -relief sunken button .f.b -width 15 -height 2 -text "Konec"\ -command exit pack .f pack .f.b -padx 32 -pady 16 Odsazení tlačítka od sousedních objektů je 32 bodů ve směru x a 16 ve směru y. button2.tcl
set myfont [font create -family {Helvetica} \ Tk: stručný průvodce Zde má tlačítko vlastní font a barvu. Jinak je vše při starém. (myfont je proměnná, font je příkaz) 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 button3.tcl
Zde je na tlačítku obrázek. Tk: stručný průvodce Zde je na tlačítku obrázek. button .b -image [image create photo -file "exit.gif"]\ -command exit pack .b -padx 8 -pady 8 button4.tcl
button .bv -text "Vymazat" -width 10\ -command vymaz Tk: stručný průvodce Ukázka vstupu a jeho zpracování. Prohlédněte si příkazy vymaz a zpracuj na následující straně. entry .en button .bv -text "Vymazat" -width 10\ -command vymaz button .bz -text "Zpracovat" -width 10\ -command zpracuj label .la -foreground #ff0000 entry1.tcl
Tk: stručný průvodce 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. pack .en -side top -padx 4 -pady 4 -fill x pack .la -side bottom -pady 4 pack .bv -side left -pady 4 pack .bz -side right -pady 4 … proc vymaz {} { .en delete 0 end } proc zpracuj {} { .la configure -text [.en get] } bind .en <Return> {zpracuj} focus .en
frame .fz -bd 2 -relief ridge entry .fz.en -width 16 Tk: stručný průvodce Zde si, prosím, povšimněte práce formátovacího příkazu pack. Podrobnější komentář naleznete na dalším snímku. frame .fz -bd 2 -relief ridge entry .fz.en -width 16 button .fz.buvy -text "Vymaz" -command vymaz button .buko -text "Konec" -command exit pack … entry2.tcl
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 4 pack .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.
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 4 pack .buko -padx 2 -pady 2 -side right -fill y
label .la -text "A pair of radio buttons" Tk: stručný průvodce Knoflíky jsou svázány s proměn-nou fo, do níž zapisují hodnoty “times“ nebo “helvetika“. 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 Všimněte si: global fo a $fo. Doplňte si příkazy pack (viz radio1.tcl). radio1.tcl
label .la -text "Two check buttons" Tk: stručný průvodce Knoflíky jsou zde svázány s proměnnými bo, it. (Příkazy pack jsou zde opět vynechány.) label .la -text "Two check buttons" checkbutton .c1 -text "Bold" -variable bo checkbutton .c2 -text "Italics" -variable it button .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" } check1.tcl
listbox .li -width 12 -height 3 label .la -text "nic" -foreground red Tk: stručný průvodce listbox .li -width 12 -height 3 label .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
scrollbar .sc -command ".li yview" Tk: stručný průvodce scrollbar .sc -command ".li yview" listbox .li -yscroll ".sc set" -height 5 label .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
Tk: stručný průvodce 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. grid .li -row 0 -column 0 grid .sc -row 0 -column 1 -sticky ns grid .la -row 1 -column 0 -columnspan 2
spinbox .sb -values {leden unor brezen duben} Tk: stručný průvodce Spinbox je entry + pomoc (zde výběr ze seznamu). Seznam hodnot je neměnný. spinbox .sb -values {leden unor brezen duben} label .la -foreground red button .bu -text OK -command buok pack … .sb set brezen proc buok {} {.la configure -text [.sb get]} spinbox1.tcl
Spinbox s čísly rostoucími o zadaný přírůstek. Tk: stručný průvodce Spinbox s čísly rostoucími o zadaný přírůstek. spinbox .sb -from 2.0 -to 3.0 -increment 0.1 label .la -foreground red button .bu -text OK -command buok pack … .sb set 2.5 proc buok {} {.la configure -text [.sb get]} spinbox2.tcl
canvas .ca -width 250 -height 150 pack .ca Tk: stručný průvodce 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. canvas .ca -width 250 -height 150 pack .ca .ca create line 25 25 125 125 -width 2 -fill red .ca create oval 125 25 225 125 -fill blue canvas1.tcl
canvas .ca -width 384 -heigh 288 pack .ca Tk: stručný průvodce Ř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. canvas .ca -width 384 -heigh 288 pack .ca image create photo "image1" -file "auto1.gif" .ca create image 2 2 -anchor nw -image "image1" .ca create oval 250 150 350 250 -fill blue canvas2.tcl
scrollbar .sy -orient vertical -command ".ca yview" Tk: stručný průvodce Povšimněte si specifikace –scrollregion “xmin ymin xmax zmax“ . Jinak je vše stejné jako u příkladu s listboxem. 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 ns grid .sx -row 1 -column 0 -sticky we .ca create … canvas3.tcl
button .b -text "Uložit a konec" -command ulozit pack … Tk: stručný průvodce Šíř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. text .t -width 24 -height 6 button .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 } text1.tcl
scale .sc -orient horizontal -length 200 -from 0\ Tk: stručný průvodce V tomto příkladě stupnice při každé změně hodnoty vyvolá příkaz scgetval a hodnotu mu předá jako parametr. scale .sc -orient horizontal -length 200 -from 0\ -to 100 -tickinterval 20 -command scgetval label .la -foreground red pack .sc pack .la -pady 8 .sc set 50 proc scgetval { val } {.la configure -text $val } scale1.tcl
frame .m -relief raised -borderwidth 1 Tk: stručný průvodce .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). 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 menu1.tcl
# Ukazka pozdejsiho nastaveni dostupnosti polozky Tk: stručný průvodce 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. # 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 menu1.tcl
Místo add command se zde použije add cascade Tk: stručný průvodce Místo add command se zde použije add cascade 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" … menu2.tcl
.m.file.menu add command -label Quit -underline 0\ Tk: stručný průvodce Akcelerátory menu .m.file.menu .m.file.menu add command -label Quit -underline 0\ -accelerator <Ctrl-c> -command exit pack … # 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 .} menu3.tcl
Menu s obrázky. Obrázky lze kombinovat s textem. Tk: stručný průvodce Menu s obrázky. Obrázky lze kombinovat s textem. 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 menu4.tcl
set types {{"Source files" {.tcl .c .h}} {"All files" *}} Tk: stručný průvodce V tomto příkladě se obsah otevřeného souboru připojí k textovému poli .t. 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 } filedialog1.tcl
tk_messageBox -title About –message\ 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
button .bu -text "Vytvorit…" \ -command noveOkno proc noveOkno { } { 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
package require Iwidgets 4.0 Tk: stručný průvodce package require Iwidgets 4.0 iwidgets::tabnotebook .tnb -width 3i -height 1.5i # Page #1 set page [.tnb add -label "Osobni"] frame $page.fr label $page.fr.laj -text "Jmeno:" entry $page.fr.enj -width 12 label $page.fr.lap -text "Prijmeni:" entry $page.fr.enp -width 12 kartoteka1.tcl
Propojení Tcl/Tk s programy/moduly v C Tk: stručný průvodce Propojení Tcl/Tk s programy/moduly v C Myšlenka propojení je tato: vytvoříte vlastní příkaz, který budete volat tak, jak je v Tcl obvyklé: 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
Propojení Tcl/Tk s programy/moduly v C Tk: stručný průvodce Propojení Tcl/Tk s programy/moduly v C Myšlenka propojení je tato: vytvoříte vlastní příkaz, který budete volat tak, jak je v Tcl obvyklé: 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
Tk: stručný průvodce - Co dál? … Podle potřeby používejte manuálu Tcl/Tk Navštivte www.tcl.tk www.scriptics.com www.activestate.com