Podíváme se na udělátka Text a Menu a vytvoříme primitivní textový editor.
Dnes si ukážeme, jak vytvořit jednoduchý textový editor. Nebude to umět žádné závratné funkce, bude nám stačit, když si ukážeme, jak uložit, otevřít dokument. V dalším díle bychom se podívali na nastavení jako barva a velikost textu. Jak jsem tedy již naznačil, celá lekce bude o udělátku Text a Menu.
Použité metody
Než se naučíme potřebné metody, měli bychom si něco říci o způsobu indexování v udělátku Text.
- Indexy jsou zpravidla dvě čísla oddělená tečkou: 1.5. První číslo značí řádek a druhé znak na řádku. Takže první písmeno bude mít index 1.0.
- Další způsob, velmi podobný prvnímu, je indexování ve tvaru "radek.end". Slouží to k získání posledního znaku na nějaké řádce. Takže poslední znak na první řádce bude 1.end.
- END - speciální proměnná označující poslední znak v udělátku.
- INSERT – tento index bude mít vždy polohou vkládacího kurzoru.
- Existují i další a o těch si případně řekneme v dalších lekcích.
text.get(start, konec)
Získá obsah udělátka Text mezi indexem start a konec. Obsah celého udělátka se tedy získá:
text.get(1.0,END)
text.delete(start, konec)
Smaže část textu mezi indexem start a konec. Takže první řádek by se smazal jako:
text.delete(1.0,"1.end")
text.index(index)
Získá index ve tvaru řádek.znak. Parametr index může obsah proměnné jako END a INSERT. Takže chceme-li získat číselnou hodnotu posledního znaku, musíme použít:
text.index(END)
Pomocné moduly
PIL
Standardně umí Tkinter pracovat pouze s obrázky ve tvaru GIF a my pomocí tohoto modulu použijeme obrázky PNG. Z modulu PIL budeme potřebovat moduly Image a ImageTk:
import Image, ImageTk
obrazek=Image.open("slunicko.png")
obrazek=ImageTk.PhotoImage(obrazek)
tkFileDialog
Náš editor bude po uživateli občas chtít, aby zadal cestu k uložení nebo otevření souboru. Bylo by nepraktické nechávat ho zadávat celou cestu ručně, takže použijeme modul tkFileDialog. My z tohoto modulu použijeme funkce askopenfilename a asksaveasfilename. Jejich funkci snadno pochopíte z malé ukázky:
# -*- coding: cp1250 -*-
import tkFileDialog
cesta=tkFileDialog.askopenfilename(title='Vyberte soubor')
print "Otevírám soubor: ",cesta
Samotný program
Takže musíme začít úvahou, co náš editor bude umět. Měl by umět hlavně otevřít, uložit a vytvořit soubor. To nám bude v dnešní lekci stačit. Nahoře bude menu, pod ním lišta a pak už samotný editor. Takže si načrtneme, jak bude vypadat naše třída:
# -*- coding: utf-8 -*-
from Tkinter import*
class Editor:
def __init__(self):
self.obrazky=[]
"vytvoření uživatelského rozhraní."
def otevrit(self):
"získa od uživatele jmeno souboru a otevře ho."
def ulozit(self):
"uloží právě otevřený dokument."
def novy_soubor(self):
"vytvoří nový soubor."
Menu
Pro vytvoření menu použijeme udělátko Menu.
hlavniMenu = Menu(self.okno)
menuSoubor = Menu(hlavniMenu, tearoff=0)
menuSoubor.add_command(label="Nový soubor")
menuSoubor.add_command(label="Otevřít")
menuSoubor.add_command(label="Uložit")
menuSoubor.add_command(label="Konec")
hlavniMenu.add_cascade(label="Soubor", menu=menuSoubor)
okno.config(menu=hlavniMenu)
Zbývá přiřadit jednotlivým tlačítkům funkci. Ta se přiřazuje pomocí parametru command.
Lišta
Lišta vlastně bude jenom rámec (frame) umístěný úplně nahoře. Šířka lišty se musí přizpůsobovat šířce okna a výška lišty se musí přizpůsobit výškám tlačítek. Takže to bude vypadat nějak takto:
self.lista=Frame(self.okno)
self.lista.pack(fill=X)
Button(self.lista,image=self.vrat_obrazek("save.png"),command=self.ulozit).pack(side=LEFT,fill=Y)
Tlačítka v liště obvykle nemívají žádný popisek, takže i my nepoužijeme text, ale obrázek. A abychom nemuseli každý obrázek, co umisťujeme v liště, otevírat samostatně, použijeme funkci vrat_obrazek:
def vrat_obrazek(self, cesta):
obr=Image.open(cesta)
obr=ImageTk.PhotoImage(obr)
self.obrazky.append(obr)
self.okno.image=self.obrazky
return obr
Podobným způsobem doděláme další tlačítka do lišty. Samozřejmě každý obrázek musíme přidat do seznamu self.obrazky, aby se každá instance uchovala. Obrázky, co jsem použil já, se dají stáhnout zde: close.png, save.png, open.png, new.png.
Editor
Nyní nám zbývá dodělat samostatný editor. Jak jsem již v úvodu naznačil, použijeme udělátko Text:
self.text=Text(self.okno)
self.text.pack(fill=BOTH,expand=1)#aby se nám Text roztáhnul přes celé okno.
Když takto vytvoříme Text, nevytvoří se posuvníky. Ale to není překážka, protože si je vytvoříme sami:
obal=Frame(self.okno)
obal.pack(fill=BOTH,expand=1)
posuvnikY=Scrollbar(obal)
posuvnikY.pack(side=RIGHT,fill=Y)
posuvnikX=Scrollbar(obal, orient=HORIZONTAL)
posuvnikX.pack(fill=X,side=BOTTOM)
self.text=Text(obal,yscrollcommand=posuvnikY.set,xscrollcommand=posuvnikX.set,wrap=NONE)
self.text.pack(fill=BOTH,expand=1)
self.text.focus_set()
posuvnikX["command"]=self.text.xview
posuvnikY["command"]=self.text.yview
Standardně by se text zalomoval, ale s použitím parametru wrap mu v tom zabráníme. self.text.focus_set() zajistí, že ihned po zapnutí bude text focus. Tím pádem máme uživatelské rozhraní a můžeme přikročit k napsání ostatních funkcí.
Otevřít
Pro získání souboru, co chce uživatel otevřít, musíme použít modul, který jsme si představili na začátku. Poté ho otevřeme a jeho obsah vložíme pomocí funkce insert do editoru:
cesta=tkFileDialog.askopenfilename(title=u"Otevřít...")
if cesta:
self.text.delete(1.0,END)
soubor=file(cesta,'r')
self.text.insert(END,soubor.read())
soubor.close()
Část if cesta je tam proto, že když uživatel zavře dialog otevírání souboru, tak proměnná cesta bude mít hodnotu None a potom by otevření souboru vyvolalo výjimku.
Uložit
Kód bude v podstatě stejný jako funkce otevrit až na to, že místo askopenfilename použijeme asksaveasfilename a místo čtení souboru do něj budeme zapisovat:
cesta=tkFileDialog.asksaveasfilename(title=u"Uložit jako...")
if cesta:
soubor=file(cesta,'w')
soubor.write(self.text.get(1.0,END))
soubor.close()
Nový dokument
V této funkci pouze vymažeme celý obsah udělátka.
Co dál?
Nemyslete si, že toto je všechno, co se dá s udělátkem Text dělat. V dalším díle se naučíme používat tagy a vyskakovací menu.